mybatis-plus#saveBatch批量保存效率低不是它的问题

634 阅读1分钟

1.mp中的saveBatch

截图.png

mp的saveBatch虽然是一条一条准备的,但到阈值(batchSize)时,才会flush一次。

flushStatements方法调用到mybatisBatchExecutor的doFlushStatements方法,最终调用到jdbc中的executeBatch方法

截图2.png

截图3.png

最终是因为executeBatch自身的行为,才导致批量操作一条条sql发送。

使用xml写sql时,我们习惯的写成 insert xxx values (?),(?)这样的形式,所以可以一次就发给mysql。

为什么不能一次将所有语句发送,而是要循环发包到mysql呢?

跟一个连接参数rewriteBatchedStatements有关。

2. statement批处理与rewriteBatchedStatements=true (启动批处理操作参数)

2.1. 不使用executeBatch()

截图4.png

2.2. 使用executeBatch(),rewriteBatchedStatements=false

截图5.png 还是一条一条执行

2.3 使用executeBatch(),rewriteBatchedStatements=true

截图.png

可以看到,变成批量的了。

3. rewriteBatchedStatements参数控制了什么?

跟踪到ClientPreparedStatement#executeBatchInternal

截图2.png

可以看到如果rewriteBatchedStatements为false,会走到executeBatchSerially(批量执行串行化)方法,从名字可以看出。。。它是一条一条执行的。

batchHasPlainStatements是一个变量,以下是其注释:

"Does the batch (if any) contain "plain" statements added by Statement.addBatch(String)? If so, we can't re-write it to use multi-value or multi-queries."

简单解释:就是说如果调用了addBatch(String参数)这个方法,则rewrite也会失效。

4. mp批量保存,rewriteBatchedStatements=true

截图3.png

使用了真正的批量处理。