You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

插入前校验需求:如何避免CodeA与TitreA字段重复?

嘿,我来帮你搞定插入Album时避免CodeA和TitreA重复的问题!首先得提一句:你当前的代码直接把对象属性拼进SQL字符串里,存在SQL注入风险,这个我会在解决方案里一起优化掉,毕竟安全第一嘛。

下面给你两种靠谱的实现思路,你可以根据自己的需求选:

方案一:应用层先校验再插入(适合简单场景)

这种方式是在执行插入前,先查一遍数据库,确认没有重复的CodeA或TitreA(你可以根据实际需求调整是单个字段唯一,还是两个字段组合唯一)。

1. 先写一个校验重复的方法

public boolean isAlbumDuplicate(String codeA, String titreA) {
    // 用参数化查询,绝对不能拼字符串!
    String checkQuery = "SELECT COUNT(*) FROM album WHERE CodeA = ? OR TitreA = ?";
    ResultSet rs = ConnexionMySQL.getInstance().executeQuery(checkQuery, codeA, titreA);
    
    try {
        if (rs.next()) {
            // 只要计数大于0,说明已有重复记录
            return rs.getInt(1) > 0;
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 别忘了关闭ResultSet,根据你的工具类实现调整
        try {
            if (rs != null) rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return false;
}

2. 修改你的插入方法,加入校验逻辑

public boolean insertAlbum(Album alb) {
    // 先校验:如果重复直接返回false
    if (isAlbumDuplicate(alb.getCodeA(), alb.getTitreA())) {
        System.out.println("警告:该CodeA或TitreA已经存在,无法插入!");
        return false;
    }
    
    // 换成参数化SQL,彻底杜绝SQL注入
    String insertSql = "INSERT INTO album (CodeA, TitreA, SortieA, IdentC) VALUES (?, ?, ?, ?)";
    boolean insertSuccess = ConnexionMySQL.getInstance().actionQuery(
        insertSql,
        alb.getCodeA(),
        alb.getTitreA(),
        alb.getSortieASQL(),
        alb.getChanteurAlb().getIdentC()
    );
    
    return insertSuccess;
}
方案二:数据库层面加唯一约束(更可靠,解决并发问题)

应用层校验有个小问题:如果两个请求同时插入相同数据,可能会因为校验和插入之间的时间差,导致重复数据漏进来。所以更稳妥的方式是让数据库帮我们兜底,加唯一约束。

1. 给表加唯一约束

如果你要保证CodeA唯一,执行这条SQL:

ALTER TABLE album ADD CONSTRAINT uk_album_codeA UNIQUE (CodeA);

如果是CodeA和TitreA组合起来唯一(比如同一歌手下标题不能重复?),就用这条:

ALTER TABLE album ADD CONSTRAINT uk_album_codeA_titreA UNIQUE (CodeA, TitreA);

2. 修改插入方法处理约束冲突

加了约束后,插入重复数据时数据库会抛出异常,我们在代码里捕获这个异常就行:

public boolean insertAlbum(Album alb) {
    try {
        String insertSql = "INSERT INTO album (CodeA, TitreA, SortieA, IdentC) VALUES (?, ?, ?, ?)";
        return ConnexionMySQL.getInstance().actionQuery(
            insertSql,
            alb.getCodeA(),
            alb.getTitreA(),
            alb.getSortieASQL(),
            alb.getChanteurAlb().getIdentC()
        );
    } catch (SQLException e) {
        // MySQL里唯一约束冲突的错误码是1062,其他数据库可能不一样,注意调整
        if (e.getErrorCode() == 1062) {
            System.out.println("该CodeA或TitreA已存在,插入失败!");
            return false;
        }
        // 其他异常正常处理
        e.printStackTrace();
        return false;
    }
}
关键提醒:一定要用参数化查询!

你原来的代码直接拼接字符串到SQL里,真的非常危险——比如如果有人把alb.getCodeA()的值设为'); DROP TABLE album; --,你的整张表都会被删掉!所以不管用哪种方案,都要换成参数化查询,上面的代码已经帮你改好了,确保你的ConnexionMySQL工具类支持这种参数化调用(如果原来的actionQuery不支持,你需要修改它,用PreparedStatement来实现)。

内容的提问来源于stack exchange,提问作者julliiie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:59:54