【mysql批量插入或更新方法实现】

2023-11-19

自定义批量插入或更新

1.创建接口,替代baseMapper

public interface RootMapper<T> extends BaseMapper<T> {

    /**
     * 自定义批量插入
     *
     * @param list
     * @return
     */
    int insertBatch(@Param("list") List<T> list);

    /**
     * 自定义批量新增或更新
     *
     * @param list
     * @return
     */
    int insertOrUpdateBatch(@Param("list") List<T> list);

2.添加方法实现类

public class InsertBatchMethod extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        final String sql = "<script>insert into %s %s values %s</script>";
        final String fieldCpcSql = prepareFieldCpcSql(tableInfo);
        final String valueCpcSql = prepareValuesCpcSql(tableInfo);
        final String sqlCpcResult = String.format(sql, tableInfo.getTableName(), fieldCpcSql, valueCpcSql);
        SqlSource sqlCpcSource = languageDriver.createSqlSource(configuration, sqlCpcResult, modelClass);
        // 第三个参数必须和RootMapper的自定义方法名一致
        return this
                .addInsertMappedStatement(mapperClass, modelClass, "insertBatch", sqlCpcSource, new NoKeyGenerator(), null,
                        null);
    }

    private String prepareFieldCpcSql(TableInfo tableInfo) {
        StringBuilder fieldCpcSql = new StringBuilder();
        fieldCpcSql.append(tableInfo.getKeyColumn()).append(",");
        tableInfo.getFieldList().forEach(x -> fieldCpcSql.append(x.getColumn()).append(","));
        fieldCpcSql.delete(fieldCpcSql.length() - 1, fieldCpcSql.length());
        fieldCpcSql.insert(0, "(");
        fieldCpcSql.append(")");
        return fieldCpcSql.toString();
    }

    private String prepareValuesCpcSql(TableInfo tableInfo) {
        final StringBuilder valueCpcSql = new StringBuilder();
        valueCpcSql.append(
                "<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
        valueCpcSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
        tableInfo.getFieldList().forEach(x -> valueCpcSql.append("#{item.").append(x.getProperty()).append("},"));
        valueCpcSql.delete(valueCpcSql.length() - 1, valueCpcSql.length());
        valueCpcSql.append("</foreach>");
        return valueCpcSql.toString();
    }
}
public class InsertOrUpdateBath extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        final String sql = "<script>insert into %s %s values %s ON DUPLICATE KEY UPDATE %s</script>";
        final String tableName = tableInfo.getTableName();
        final String filedSql = prepareFieldSql(tableInfo);
        final String modelValuesSql = prepareModelValuesSql(tableInfo);
        final String duplicateKeySql =prepareDuplicateKeySql(tableInfo);
        final String sqlResult = String.format(sql, tableName, filedSql, modelValuesSql,duplicateKeySql);
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
        return this.addInsertMappedStatement(mapperClass, modelClass, "insertOrUpdateBatch", sqlSource, new NoKeyGenerator(), null, null);
    }

    /**
     * 准备ON DUPLICATE KEY UPDATE sql
     * @param tableInfo
     * @return
     */
    private String prepareDuplicateKeySql(TableInfo tableInfo) {
        final StringBuilder duplicateKeySql = new StringBuilder();
        if(!StringUtils.isEmpty(tableInfo.getKeyColumn())) {
            duplicateKeySql.append(tableInfo.getKeyColumn()).append("=values(").append(tableInfo.getKeyColumn()).append("),");
        }

        tableInfo.getFieldList().forEach(x -> duplicateKeySql.append(x.getColumn())
                .append("=values(")
                .append(x.getColumn())
                .append("),"));
        duplicateKeySql.delete(duplicateKeySql.length() - 1, duplicateKeySql.length());
        return duplicateKeySql.toString();
    }

    /**
     * 准备属性名
     * @param tableInfo
     * @return
     */
    private String prepareFieldSql(TableInfo tableInfo) {
        StringBuilder fieldCpcSql = new StringBuilder();
        fieldCpcSql.append(tableInfo.getKeyColumn()).append(",");
        tableInfo.getFieldList().forEach(x -> fieldCpcSql.append(x.getColumn()).append(","));
        fieldCpcSql.delete(fieldCpcSql.length() - 1, fieldCpcSql.length());
        fieldCpcSql.insert(0, "(");
        fieldCpcSql.append(")");
        return fieldCpcSql.toString();
    }

    private String prepareModelValuesSql(TableInfo tableInfo){
        final StringBuilder valuepCpcSql = new StringBuilder();
        valuepCpcSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
        if(!StringUtils.isEmpty(tableInfo.getKeyProperty())) {
            valuepCpcSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
        }
        tableInfo.getFieldList().forEach(x -> valuepCpcSql.append("#{item.").append(x.getProperty()).append("},"));
        valuepCpcSql.delete(valuepCpcSql.length() - 1, valuepCpcSql.length());
        valuepCpcSql.append("</foreach>");
        return valuepCpcSql.toString();
    }
}

3.在实际使用的mapper上修改继承类为创建的RootMapper
4.然后就可以调用批量插入或更新方法了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【mysql批量插入或更新方法实现】 的相关文章

随机推荐

  • 解决SqlServer批量插入最多2100条数据的方法

    SqlServer批量插入数据时最多不能超过2100条 记录一下解决办法 Java代码 public void batchInsert List
  • 基于vue实现移动端点击上方导航,内容滑动切换,滑动内容导航自动切换。

    这是在日常开发过程中常见的选项卡 带滑动切换效果 小白一枚 不足之处还望体谅 包涵 这也是第一次尝试写博客 以后会继续分享一些工作中的问题与收获 实现效果 点击上方导航 当前导航添加样式 下方内容滑动切换 滑动下方内容上面导航切换 第一步
  • 论文笔记:Region Representation Learning via Mobility Flow

    2017 CIKM 1 摘要和介绍 使用出租车出行数据学习区域向量表征 同时考虑时间动态和多跳位置转换 gt 通过flow graph和spatial graph学习表征 出租车交通流可以作为区域相似度的一种 A区域和B区域之间流量大 gt
  • JS 变量提升和函数提升

    变量提升 这里介绍一个变量提升提升的经典案例 for var i 0 i lt 10 i setTimeout gt console log i 1000 这里打印是10个10 因为在执行第一个setTimeout时 Js不会等待1秒后再去
  • 怎么解决“无法打开包括文件:“graphics.h”: No such file or directory”的问题

    在接手同伴的中国象棋项目时 导入项目后 发现VS一直提示 无法打开包括文件 graphics h No such file or directory 在查阅资料后发现是缺少easyx文件 接下来 就介绍一下手动配置一下easyx文件 eas
  • 特殊类型动归--区间动归与环形动归

    区间动归 某类有序事件中前若干个事件的子答案 不能再支撑状态转移 我们需要去寻找 从某个元素起到另一个元素结束所包含所有的 连续 元素的子答案 作为状态 可以想象 在这个描述下 每个状态会对应于原题序列上的一个区间 区间具有良好的性质 短的
  • 深度学习(1):BP神经网络实现银行客户流失预测

    目的 针对银行客户行为和统计数据实现客户流失预测任务 一 数据准备 1 数据集 select data csv 作为训练样本 数据预处理方式 归一化 数值化 CreditScore 信用分数 EB 存贷款情况 EstimatedSalary
  • centos 建立回收站

    linux下的回收站在每一个当前用户目录 local share Trash中 也可以给linux添加一个回收站 mkdir tmp trash tmp 建立一个回收站目录 vi bin trash 编辑一个文件 mv tmp trash
  • python之浅拷贝、深拷贝

    什么是浅拷贝 深拷贝 理论来自python基础教程 在 Python 中 对象赋值实际上是对象的引用 当创建一个对象 然后把它赋给另一个变量的时候 Python 并没有拷贝这个对象 而只是拷贝了这个对象的引用 我们称之为浅拷贝 在 Pyth
  • 腾讯云 Finops Crane 开发者集训营 - 云原生如何助力企业搞定成本优化

    引言 随着docker的技术普及 越来越多的企业加入了云计算发展进程 云原生产业发展迅猛 云原生建设投入比例明显 面对大规模的集群投入 部署 维护等问题也逐渐产生 越来越多的企业对云原生不断提出更高要求 同时云原生技术简化运维的效能提 升开
  • .Net WebAPI 高速下载文件接口实现

    接触WebAPI一年多了 感觉是个承上启下 开创未来的技术 老一辈程序员写接口就像写方法一样 不需要了解太多网页的知识 却可以在浏览器中访问这些接口 由于是基于HTTP协议 因此不管是PC 手机还是嵌入式均可顺利访问 对于当下软件多终端的设
  • Spark 【分区与并行度】

    RDD 并行度和分区 SparkConf setMaster local 我们在创建 SparkContext 对象时通常会指定 SparkConf 参数 它包含了我们运行时的配置信息 如果我们的 setMaster 中的参数是 local
  • 服务器维护中轩辕,轩辕服务器为什么老是-轩辕服务器为什么 – 手机爱问

    网三轩辕为什么上不去了啊 网三轩 朋友 我先问下 有以下的情况吗 第一 你的号上去后 选线的时候是不是请重从连接 要是的话这是卡号了 第二 你上号的时候 写账号和密码 就提事说 从请从新登陆 这不是卡号 这也是卡线了 这是你卡线的时候总来回
  • xray扫描器的使用 (长亭科技公司创造)

    简介 xray是一款可以使用HTTP HTTPS代理进行被动扫描的安全工具 支持功能如下 独立的 URL 扫描 基于 HTTP 的被动代理扫描 同时支持HTTPS SQL注入检测模块 命令注入检测模块 任意重定向检测模块 路径遍历模块 Xr
  • c# Newtonsoft.Json 常用方法总结

    1 实体类的 Json 序列化和反序列化 我们以如下的 Person 类举例 其中包含了常用的数据类型 public class Person public int ID get set public string Name get set
  • Kubernetes之kubectl命令详解及常用示例

    文章目录 一 kubectl语法 二 子命令详解 1 command 2 type 3 flags 4 kubectl的输出格式 三 kubectl常用命令 1 查看类命令 2 操作类命令 3 其他操作 一 kubectl语法 kubect
  • 容器与云的碰撞——一次对MinIO的测试

    事先声明 本次测试过程完全处于本地或授权环境 仅供学习与参考 不存在未授权测试过程 本文提到的漏洞 MinIO未授权SSRF漏洞 CVE 2021 21287 已经修复 也请读者勿使用该漏洞进行未授权测试 否则作者不承担任何责任 随着工作和
  • OAuth2.0-授权码模式

    解决问题 OAuth2 0授权码模式主要解决了信任问题 一个第三方网站需要访问我们Github上的数据 例如用户头像 那Github为什么要信任该网站 该对网站信任到什么程度 如果彻底信任该网站 那么将Github的用户名和密码直接交给该网
  • 计算机网路基础 - 一些基本概念与网络结构

    1 基本概念 计算机网络 通信技术 计算机技术 是两项技术紧密结合的产物 通信系统的基础模型 计算机网络 是指将地理位置不同 具有独立功能的多台计算机及其外部设备 通过通信线路连接 在网络操作系统 网络管理软件及网络通信协议的管理和协调下
  • 【mysql批量插入或更新方法实现】

    自定义批量插入或更新 1 创建接口 替代baseMapper public interface RootMapper