【SpringBoot DB系列】Jooq批量写入采坑记录
后面介绍了jooq的三种批量插入方式,后果最近发现这外面竟然还有一个深坑,我认为的批量插入竟然不是一次插入多条数据,而是一条一条的插入...,这就有点尬了
<!-- more -->
1. 三种插入姿态
对于我的项目创立以及jooq的相干应用姿态,举荐查看之前的博文: 【DB系列】Jooq之新增记录应用姿态
上面是咱们采纳的三种批量插入方式
/** * 通过Record执行批量增加 * * 通过源码查看,这种插入方式实际上是单条单条的写入数据,和上面的一次插入多条有本质区别 * * @param list * @return */public boolean batchSave(List<PoetBO> list) { List<PoetPO> poList = list.stream().map(this::bo2po).collect(Collectors.toList()); int[] ans = dsl.batchInsert(poList).execute(); System.out.println(JSON.toJSONString(ans)); return true;}/** * 类sql写法,批量增加 * * @param list * @return */public boolean batchSave2(List<PoetBO> list) { InsertValuesStep2<PoetPO, Integer, String> step = dsl.insertInto(table).columns(table.ID, table.NAME); for (PoetBO bo : list) { step.values(bo.getId(), bo.getName()); } return step.execute() > 0;}/** * 不基于主动生成的代码,来批量增加数据 * * @param list * @return */public boolean batchSave3(List<PoetBO> list) { InsertQuery insertQuery = dsl.insertQuery(DSL.table("poet")); for (PoetBO bo : list) { insertQuery.addValue(DSL.field("id", Integer.class), bo.getId()); insertQuery.addValue(DSL.field("name", String.class), bo.getName()); insertQuery.newRecord(); } return insertQuery.execute() > 0;}
请留神下面的三种批量插入方式,基本上对应的就是jooq的三种常见的用法
- 间接借助主动生成的
Record
类来操作 - 类sql的拼接写法,基本上咱们平时的sql怎么写,这里就怎么用
InsertQuery
:借助jooq提供的各种Query类来执行指标操作
2. 日志验证
下面三种写法中,第一种批量插入方式,并不是咱们传统了解的一次插入多条记录,相同它是一条一条的插入的,咱们能够通过开启jooq的日志来查看一些执行的sql状况
配置文件 application.properties
,增加上面的配置
debug=falsetrace=falselogging.level.org.jooq=DEBUG
如果有本人的logback.xml
配置文件,能够调整一下日志级别,将jooq的debug日志放进去
一个简略的测试case
public void test() { this.batchSave(Arrays.asList(new PoetBO(14, "yh"), new PoetBO(15, "yhh"))); this.batchSave2(Arrays.asList(new PoetBO(16, "yihui"), new PoetBO(17, "yihuihui"))); this.batchSave3(Arrays.asList(new PoetBO(18, "YiHui"), new PoetBO(19, "YiHuiBlog")));}
从下面的sql来看,前面两个的确是一次插入多条,然而第一个,也没有将具体执行的sql打印进去,所有不看源码的话,也没有方法实锤是一条一条插入的
为了验证这个问题,一个简略的解决办法就是批量插入两条数据,第一条失常,第二条异样,如果第一条插入胜利,第二条失败那就大概率是单个插入的了
// 表构造中,name的字段最大为20,上面插入的第二条数据长度超限try { this.batchSave(Arrays.asList(new PoetBO(14, "yh"), new PoetBO(15, "1234567890098765432112345")));} catch (Exception e) { e.printStackTrace();}try { this.batchSave2(Arrays.asList(new PoetBO(16, "yihui"), new PoetBO(17, "1234567890098765432112345")));} catch (Exception e) { e.printStackTrace();}this.batchSave3(Arrays.asList(new PoetBO(18, "YiHui"), new PoetBO(19, "YiHuiBlog")));
第一种批量插入失败
第二种插入失败
插入后后果
请留神下面的报错,以及最终插入的后果,第一种插入方式一个插入胜利一个失败;第二种批量插入方式,两条都插入失败;
通常状况下,一次插入多条数据时,一个插入失败,会导致整个插入都失败,如下
3. 源码剖析
下面是从日志以及后果体现来揣测理论的执行状况,接下来就须要从源码角度来看一下,是否真的是单个的执行了
省略掉具体的定位过程,间接找到org.jooq.impl.BatchCRUD#execute
,对应的代码
@Overridepublic final int[] execute() throws DataAccessException { // [#1180] Run batch queries with BatchMultiple, if no bind variables // should be used... if (executeStaticStatements(configuration.settings())) { return executeStatic(); } else { return executePrepared(); }}
下面有两种插入方式,对于插入的外围逻辑一样
遍历汇合,获取单个 record,执行 CURD
II. 其余
0. 我的项目
系列博文
- 【SpringBoot DB系列】Jooq之记录更新与删除
- 【SpringBoot DB系列】Jooq之新增记录应用姿态
- 【SpringBoot DB系列】Jooq代码主动生成
- 【SpringBoot DB系列】Jooq初体验
我的项目源码
- 工程:https://github.com/liuyueyi/spring-boot-demo
- 我的项目源码: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/108-jooq-curd
1. 一灰灰Blog
尽信书则不如,以上内容,纯属一家之言,因集体能力无限,不免有疏漏和谬误之处,如发现bug或者有更好的倡议,欢送批评指正,不吝感谢
上面一灰灰的集体博客,记录所有学习和工作中的博文,欢送大家前去逛逛
- 一灰灰Blog集体博客 https://blog.hhui.top
- 一灰灰Blog-Spring专题博客 http://spring.hhui.top