MyBatis批量插入(MySql进行无数据插入,有数据更新)

ok,先来原理:

当在MySql进行插入时,触发了唯一键冲突,一般会报错,但是

vbnet 复制代码
ON DUPLICATE KEY UPDATE

使用这个可以实现更新的目的。

那么条件来了,要有触发了唯一键冲突,那么你就要在表中给除id外的字段,唯一建UNIQUE的唯一索引,当然也可以多个字段一起,但是注意,当所有字段设定的长度太长时,不会创建,即相关字段不能很长很长,不过一般都是id,问题不大。

在xml中,粗略格式(当然你要在注解中也可以)

ini 复制代码
<insert id="saveOrUpdateBatch">
    INSERT INTO bs_jackyun_check_info
    ( platform,checkNo。。。 )
    VALUES
    <foreach item="item" index="index" collection="list" separator=",">
        ( #{item.platform},#{item.checkNo}。。。)
    </foreach>
    ON DUPLICATE KEY UPDATE
    // 如果有数据要进行更新的字段 platform = VALUES( platform )这种模式
    platform = VALUES( platform ),check_no = VALUES( check_no )。。。
</insert>

然后附上一个生成这个的sql的方法,不过潦草,哈哈哈哈哈

不过需要注意一点点小地方

第一

go 复制代码
这里是,你没有@TableField(exist = false)注解,但是这个字段又不想更新的地方,当然自定义注解什么的也可以,但是我不想写

// 不存在于名单中进行更新
String[] whiteList = {"isAudit", "reportNumber"};
if (!StringUtils.ifMatches(field.getName(),whiteList)) {
    // 构建更新字段
    updateSql.append(name).append(" = VALUES( ").append(name).append(" ),");
}

第二

go 复制代码
这里,你可能需要补充基类的字段,
// 补充基类字段
builder.append(" id, create_by, create_time, update_by, update_time, del_flag, group_id ");

还有这里

go 复制代码
updateSql.append(" update_by = VALUES(update_by), update_time = VALUES(update_time)");
builder.append(" ) ").append("\n").append("VALUES ").append("\n");

以及这里

ruby 复制代码
builder.append(",#{item.id},#{item.createBy},#{item.createTime},#{item.updateBy},#{item.updateTime},#{item.delFlag},#{item.groupId}");

OK,那完整的代码在下面,可能有些潦草,如果需要使用请按自己的需求更改

ini 复制代码
public static void sdssas(Class<?> entityClass){
    StringBuilder builder = new StringBuilder();
    StringBuilder updateSql = new StringBuilder();
    builder.append("INSERT INTO ");
    // 获取表名
    TableName annotation = entityClass.getAnnotation(TableName.class);
    String tableName = annotation.value();
    builder.append(tableName).append("\n").append(" ( ");
    // 获取属性
    Field[] declaredFields = entityClass.getDeclaredFields();
    CopyOnWriteArrayList<String> fieldNameList = new CopyOnWriteArrayList<>();
    // 按属性设置sql字段
    Arrays.stream(declaredFields).forEach(field -> {
        TableField tableField = field.getAnnotation(TableField.class);
        if (tableField == null || tableField.exist()){
            // 转驼峰命名
            String name = StringUtils.toUnderScoreCase(field.getName());
            fieldNameList.add(field.getName());
            builder.append(name).append(",");
            // 不存在于名单中进行更新
            String[] whiteList = {"isAudit", "reportNumber"};
            if (!StringUtils.ifMatches(field.getName(),whiteList)) {
                // 构建更新字段
                updateSql.append(name).append(" = VALUES( ").append(name).append(" ),");
            }
        }
    });
    // 补充基类字段
    builder.append(" id, create_by, create_time, update_by, update_time, del_flag, group_id ");

    updateSql.append(" update_by = VALUES(update_by), update_time = VALUES(update_time)");
    builder.append(" ) ").append("\n").append("VALUES ").append("\n");
    builder.append("<foreach item="item" index="index" collection="list" separator=",">").append("\n");
    builder.append(" ( ");
    fieldNameList.stream().forEachOrdered(fieldName -> {
        builder.append("#{item.").append(fieldName).append("},");
    });
    builder.delete(builder.length()-1,builder.length());
    builder.append(",#{item.id},#{item.createBy},#{item.createTime},#{item.updateBy},#{item.updateTime},#{item.delFlag},#{item.groupId}");
    builder.append(")").append("\n");
    builder.append("</foreach>").append("\n");
    builder.append(" ON DUPLICATE KEY UPDATE ").append("\n");
    builder.append(updateSql);
    System.out.println(builder.toString());
}

感谢:

# MySql批量插入数据,已经存在的更新,不存在新增

相关推荐
谢亮_vipxieliang7 小时前
Go defer、panic与recover核心知识点
开发语言·后端·golang
颜进强8 小时前
17 · 自定义 Provider 四形态:useValue / useClass / useFactory / useExisting 到底在选什么
前端·后端·ai编程
碎觉崽8 小时前
我的 QQ 机器人被腾讯反复踢下线,折腾了半个月才搞明白
后端
打工仔折腾 AI8 小时前
从零写一个CAD 05:以鼠标为中心的滚轮缩放矩阵顺序不能反
后端·python·线性代数·性能优化·矩阵·计算机外设·ai agent 实战
谢亮_vipxieliang8 小时前
Go基础数据类型全解
开发语言·后端·golang
专业程序开发源8 小时前
springboot古城景区管理系统88564-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
小蒜学长9 小时前
基于微信小程序的遇见咖啡店点餐系统设计与实现(代码+数据库+LW)
java·spring boot·后端·微信小程序·咖啡店点餐系统
小蒜学长9 小时前
基于SSM+VUE的电影售票平台的设计与实现(代码+数据库+LW)
java·vue.js·spring boot·后端·ssm框架·电影售票平台
code2cat9 小时前
【随笔】MCP工具错误怎样分层:先读反馈,再决定下一步
开发语言·后端·ai agent·mcp
专业程序开发源9 小时前
springboot酒店会员点餐系统22339-计算机课程设计、毕业设计
java·javascript·vue.js·spring boot·后端·php·课程设计