我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Mybatis批量插入数据的两种方式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Mybatis批量插入数据的两种方式

总体描述

软件开发过程中需要批量插入数据的场景有几种:

  1. 从离线文件(excel, csv等)导入大批量数据到系统。
  2. 从其它系统定时或者人工同步大批量数据到系统。
  3. 程序自身的某些算法执行时会生成大批量数据保存到数据库。

上面这些场景都是长时间的处理过程,在软件设计时需要将其设计成带进度展示的异步任务(同步任务微服务有http请求超时的风险)。异步任务可以使用消息框架。

使用批量插入技术能提升数据持久化的性能。用mybatis有两种批量插入数据的方式可选:1. 拼接批量插入多条数据的SQL. 2. 使用Batch Insert技术。

方式一:拼接插入多条数据的SQL

mapper接口代码

        void insertDataList(@Param("list") List<BatchData> dataList);

XML文件配置

    <insert id="batchInsertData" useGeneratedKeys="true" keyColumn="id" keyProperty="id">        INSERT INTO t_batch_data (            column1,            column2,            column3,            column4,            column5,            column6,            column7,            column8,            column9,            column10        ) VALUES        <foreach item="data" collection="list" separator=",">            (                #{data.column1},                #{data.column2},                #{data.column3},                #{data.column4},                #{data.column5},                #{data.column6},                #{data.column7},                #{data.column8},                #{data.column9},                #{data.column10}            )        foreach>    insert>

可以看到,XML配置文件使用 foreach 对多条数据做了拼接,Value部分用逗号分隔。拼接后的SQL样式:

INSERT INTO t_batch_data (            column1,            column2,            column3,            column4,            column5,            column6,            column7,            column8,            column9,            column10        ) VALUES                      (                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?            )         ,             (                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?            )         ,             (                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?,                ?            )

可以看到,拼接的SQL长度跟批量插入数据的条数和单条数据的字段数相关。对于像postgres这样限定了参数个数的数据库,需要提前对大批量数据做拆分处理。

下面的示例代码对批量数据按200条一组做拆分,然后再入库。

    public long foreachBatchInsert(@PathVariable("amount") int amount) {        long beginTime = System.currentTimeMillis();        List<BatchData> dataList = buildDataList(amount);        // 大数据分批处理入库        List<List<BatchData>> dataGroup = ListUtil.splitList(dataList, 200);        for (List<BatchData> group : dataGroup) {            batchInsertMapper.insertDataList(group);        }        return System.currentTimeMillis() - beginTime;    }

方式二: 使用Batch Insert技术

Mapper接口代码

        void insertData(@Param("data") BatchData data);

XML文件配置

    <insert id="insertData" useGeneratedKeys="true" keyProperty="data.id" keyColumn="id">        INSERT INTO t_batch_data (            column1,            column2,            column3,            column4,            column5,            column6,            column7,            column8,            column9,            column10        ) VALUES (            #{data.column1},            #{data.column2},            #{data.column3},            #{data.column4},            #{data.column5},            #{data.column6},            #{data.column7},            #{data.column8},            #{data.column9},            #{data.column10}        )    insert>

映射实例接口和SQL代码与插入单个对象无异。关键代码在应用层。

应用层代码

    public long mybatisBatchInsert(@PathVariable("amount") int amount) {        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false);        long beginTime = System.currentTimeMillis();        try {            BatchInsertMapper insertMapper = session.getMapper(BatchInsertMapper.class);            List<BatchData> dataList = buildDataList(amount);            for (BatchData data : dataList) {                insertMapper.insertData(data);            }            session.commit();            session.clearCache();        } catch (Exception e) {            session.rollback();        } finally {            session.close();        }        return System.currentTimeMillis() - beginTime;    }

查看打印出执行的SQL语句:

INSERT INTO t_batch_data (            column1,            column2,            column3,            column4,            column5,            column6,            column7,            column8,            column9,            column10        ) VALUES (            ?,            ?,            ?,            ?,            ?,            ?,            ?,            ?,            ?,            ?        )

拦截StatementHandler的prepare执行方法,可以看到只执行了一次预编译。批量插入不会出现参数个数超限或者SQL语句超长的问题。

对比分析

性能对比

在postgres数据库中新建了一个包含10个text类型字段的表(t_batch_data)验证了一下,插入20万条数据时间都在15秒左右,相差不大。方案1必须做分组(参数个数超过限制);方案二本身是调用的mapper的插入单个对象的接口, 不需要做分批。

应用场景分析

如表字段是固定的,字段数量也不大可以使用方案一;如表字段数量不固定(元数据驱动)推荐使用第二种方案。第二种方案在代码执行到session.commit()时数据才真正入库,如果在这之前使用数据库的数据或者回填的自增ID是有问题的。

实际产品开发过程中,即使采用第二种方案也建议对大数量做分组处理,将单次操作数据库的时间控制在2秒以内。

Demo代码地址: https://github.com/ylforever/elon-postgres.git

来源地址:https://blog.csdn.net/ylforever/article/details/126592028

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Mybatis批量插入数据的两种方式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Mybatis批量插入数据的两种方式总结与对比

批量插入功能是我们日常工作中比较常见的业务功能之一,下面这篇文章主要给大家介绍了关于Mybatis批量插入数据的两种方式总结与对比的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-01-30

MyBatis批量插入的五种方式小结(MyBatis以集合方式批量新增)

本文主要介绍了MyBatis批量插入的五种方式小结(MyBatis以集合方式批量新增),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-01-09

Mybatis批量插入大量数据的最优方式总结

批量插入功能是我们日常工作中比较常见的业务功能之一,下面这篇文章主要给大家总结介绍了关于Mybatis批量插入大量数据的几种最优方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-03-19

数据库批量插入数据的三种方法

一、准备工作 测试环境:SpringBoot项目+MybatisPlus框架+MySQL数据库+Lombok 二、导入依赖 dependency> groupId>org.springframework.boot
2023-08-20

MyBatis如何批量插入大量数据

这篇文章将为大家详细讲解有关MyBatis如何批量插入大量数据,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。问题背景:只用MyBatis中foreach进行批量插入数据,一次性插入超过一千条的时候MyBa
2023-06-22

Mybatis批量插入大量数据的方法有哪些

本文小编为大家详细介绍“Mybatis批量插入大量数据的方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Mybatis批量插入大量数据的方法有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Mybat
2023-07-05

MyBatis中怎么批量插入数据

在MyBatis中,可以使用foreach标签来实现批量插入数据。具体步骤如下:创建一个Mapper接口,定义一个insertBatch方法用于批量插入数据。public interface UserMapper {void insertB
MyBatis中怎么批量插入数据
2024-03-07

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录