广东建网站的公司,网站logo织梦怎么做,大宗商品交易软件哪个好,互联网公司排名广州在之前的优惠券兑换码需求中#xff0c;涉及批量写入问题#xff0c;其中有一个关键的连接配置参数非常重要——rewriteBatchedStatements#xff0c;当该值配置为true时#xff0c;Statement将可能对批量插入sql进行重写。
何谓重写#xff1f;原来提交的批量执行语句涉及批量写入问题其中有一个关键的连接配置参数非常重要——rewriteBatchedStatements当该值配置为true时Statement将可能对批量插入sql进行重写。
何谓重写原来提交的批量执行语句100条如下
INSERT INTO dh_redeem_code (code, status, coupon_id, batch_id) VALUES (1,0,100,1);
INSERT INTO dh_redeem_code (code, status, coupon_id, batch_id) VALUES (2,0,100,1);
...
INSERT INTO dh_redeem_code (code, status, coupon_id, batch_id) VALUES (100,0,100,1);
重写之后的sql语句1条如下
INSERT INTO dh_redeem_code (code, status, coupon_id, batch_id) VALUES
(1,0,100,1),
(2,0,100,1),
...
(100,0,100,1);
本文将从源码层面来对该参数的作用进行分析。笔者采用的mysql数据库驱动依赖库为mysql-connector-java:8.0.30。
首先我们来看一段ClientPreparedStatement.executeBatchInternal()方法的代码这是数据库驱动内部执行批量sql的方法。
if (!this.batchHasPlainStatements this.rewriteBatchedStatements.getValue()) {if (getQueryInfo().isRewritableWithMultiValuesClause()) {return executeBatchWithMultiValuesClause(batchTimeout);}if (!this.batchHasPlainStatements this.query.getBatchedArgs() ! null this.query.getBatchedArgs().size() 3 /* cost of option setting rt-wise */) {return executePreparedBatchAsMultiStatement(batchTimeout);}
}
关于batchHasPlainStatements属性如果批处理使用 Statement.addBatchString 显示添加sql语句则该属性值为true否则为false。原文如下
/*** Does the batch (if any) contain plain statements added by Statement.addBatch(String)?* If so, we cant re-write it to use multi-value or multi-queries.*/
protected boolean batchHasPlainStatements false;
第一行代码的意思如果没有使用 Statement.addBatchString 显示添加sql语句并且rewriteBatchedStatements参数值为true则有可能对批量语句进行重写。
继续往下看isRewritableWithMultiValuesClause这个属性值为true则执行executeBatchWithMultiValuesClause方法该方法实现对sql语句的重写。
对于isRewritableWithMultiValuesClause属性的赋值QueryInfo类的构造函数中
public QueryInfo(String sql, Session session, String encoding) {// Check if the statement has potential to be rewritten as a multi-values clause statement, i.e., if it is an INSERT or REPLACE statement and// rewriteBatchedStatements is enabled.boolean rewritableAsMultiValues (isInsert || isReplace) rewriteBatchedStatements;... //这里有很长很长很长一段代码this.isRewritableWithMultiValuesClause rewritableAsMultiValues;
}
从第4行代码看出重写的必要条件rewriteBatchedStatements值为true而且必须是插入操作或者REPLACE操作。
再来看看sql语句重写函数executeBatchWithMultiValuesClause(batchTimeout)代码
batchedStatement /* FIXME -if we ever care about folks proxying our JdbcConnection */prepareBatchedInsertSQL(locallyScopedConn, numValuesPerBatch);timeoutTask startQueryTimer(batchedStatement, batchTimeout);numberToExecuteAsMultiValue numBatchedArgs numValuesPerBatch ? numBatchedArgs : numBatchedArgs / numValuesPerBatch;int numberArgsToExecute numberToExecuteAsMultiValue * numValuesPerBatch;for (int i 0; i numberArgsToExecute; i) {if (i ! 0 i % numValuesPerBatch 0) {try {updateCountRunningTotal batchedStatement.executeLargeUpdate();} catch (SQLException ex) {sqlEx handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);}getBatchedGeneratedKeys(batchedStatement);batchedStatement.clearParameters();batchedParamIndex 1;}batchedParamIndex setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter));
}try {updateCountRunningTotal batchedStatement.executeLargeUpdate();
} catch (SQLException ex) {sqlEx handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
}getBatchedGeneratedKeys(batchedStatement);
上述代码第一行将根据批量sql数量和插入的字段数量构建带有占位符的sql。随后的语句遍历批量sql使用实际的插入参数值替换占位符从而形成一条可执行的批量插入语句。
自此关于rewriteBatchedStatements的源码分析结束如果需要数据库驱动重写批量插入只需要正常使用MybatisPlus的saveBatch方法并在数据库连接中加上rewriteBatchedStatementstrue的配置信息即可。