mybatis-plus批量插入生效條件和源碼分析
代碼
com.baomidou.mybatisplus.extension.service.IService#saveBatch(java.util.Collection<T>)
源碼實現
可以看到使用的是ExecutorType.BATCH執行器
mybatis中BATCH執行器源碼
如圖可以看到使用的是JDBC底層的addBatch方法,最后flush中調用executeBatch真正開始執行
JDBC層(mysql-connector-java:8)
protected long[] executeBatchInternal() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.connection.isReadOnly()) {
throw new SQLException(Messages.getString("PreparedStatement.25") + Messages.getString("PreparedStatement.26"),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT);
}
if (this.query.getBatchedArgs() == null || this.query.getBatchedArgs().size() == 0) {
return new long[0];
}
// we timeout the entire batch, not individual statements
int batchTimeout = getTimeoutInMillis();
setTimeoutInMillis(0);
resetCancelledState();
try {
statementBegins();
clearWarnings();
//batch不包含sql字符串,並且開啟rewriteBatchedStatements
if (!this.batchHasPlainStatements && this.rewriteBatchedStatements.getValue()) {
//判斷是否可以改寫為mutil-value insert
if (((PreparedQuery<?>) this.query).getParseInfo().canRewriteAsMultiValueInsertAtSqlLevel()) {
return executeBatchedInserts(batchTimeout);
}
//batch數量大於3,通過multi statement執行sql
if (!this.batchHasPlainStatements && this.query.getBatchedArgs() != null
&& this.query.getBatchedArgs().size() > 3 /* cost of option setting rt-wise */) {
return executePreparedBatchAsMultiStatement(batchTimeout);
}
}
//順序執行
return executeBatchSerially(batchTimeout);
} finally {
this.query.getStatementExecuting().set(false);
clearBatch();
}
}
}
如上代碼注釋批量執行的基本條件要開啟rewriteBatchedStatements並且沒有plain sql