博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
笔记笔记笔记
阅读量:38356 次
发布时间:2022-02-11

本文共 2732 字,大约阅读时间需要 9 分钟。

拼接插入多条数据的SQL

mapper接口代码

/**

* 插入数据列表

*

* @param dataList 数据列表

*/

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接口代码

/**

* 插入单条数据

*

* @param data PO数据

*/

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语句超长的问题。

转载地址:http://tkwduy.baihongyu.com/

你可能感兴趣的文章
最近经历的一些大数据(Spark/Hadoop)面试题
查看>>
Hadoop MapReduce原理及实例
查看>>
Java 集合系列目录(Category)
查看>>
redis永久设置或取消密码
查看>>
Git .gitignore配置学习
查看>>
git remote 删除添加的远程地址
查看>>
LeetCode 338. 比特位计数
查看>>
LeetCode 190. 颠倒二进制位
查看>>
LeetCode 268. 丢失的数字
查看>>
LeetCode 231. 2 的幂
查看>>
LeetCode 191. 位1的个数
查看>>
LeetCode 476. 数字的补数
查看>>
LeetCode 342. 4的幂
查看>>
El表达式
查看>>
springboot banner打印,控制台springboot图案怎么来的
查看>>
linux shell內建命令区分--type
查看>>
java--打印当前项目加载的jar包--getResources
查看>>
mybatis 学习记录(3)—— 动态 sql
查看>>
mybatis 学习记录(4.1)—— 级联查询(无 association 和 collection)
查看>>
面试官:说说快速失败和安全失败是什么
查看>>