[jOOQ/jOOQ#10693] Add Settings.batchSize to transparently specify a maximum batch size for BatchedConnection

This commit is contained in:
Lukas Eder 2020-09-25 14:22:54 +02:00
parent 20e0972e5b
commit 6bc0793cde
6 changed files with 75 additions and 10 deletions

View File

@ -196,6 +196,8 @@ public class Settings
protected Integer maxRows = 0;
@XmlElement(defaultValue = "0")
protected Integer fetchSize = 0;
@XmlElement(defaultValue = "2147483647")
protected Integer batchSize = 2147483647;
@XmlElement(defaultValue = "true")
protected Boolean debugInfoOnStackTrace = true;
@XmlElement(defaultValue = "false")
@ -1745,6 +1747,22 @@ public class Settings
this.fetchSize = value;
}
/**
* A property specifying a batch size that should be applied to all automatically created {@link org.jooq.tools.jdbc.BatchedConnection} instances.
*
*/
public Integer getBatchSize() {
return batchSize;
}
/**
* A property specifying a batch size that should be applied to all automatically created {@link org.jooq.tools.jdbc.BatchedConnection} instances.
*
*/
public void setBatchSize(Integer value) {
this.batchSize = value;
}
/**
* [#5570] Whether exception stack traces should be enhanced with additional debug information.
*
@ -2794,6 +2812,15 @@ public class Settings
return this;
}
/**
* A property specifying a batch size that should be applied to all automatically created {@link org.jooq.tools.jdbc.BatchedConnection} instances.
*
*/
public Settings withBatchSize(Integer value) {
setBatchSize(value);
return this;
}
public Settings withDebugInfoOnStackTrace(Boolean value) {
setDebugInfoOnStackTrace(value);
return this;
@ -3098,6 +3125,7 @@ public class Settings
builder.append("queryTimeout", queryTimeout);
builder.append("maxRows", maxRows);
builder.append("fetchSize", fetchSize);
builder.append("batchSize", batchSize);
builder.append("debugInfoOnStackTrace", debugInfoOnStackTrace);
builder.append("inListPadding", inListPadding);
builder.append("inListPadBase", inListPadBase);
@ -3741,6 +3769,15 @@ public class Settings
return false;
}
}
if (batchSize == null) {
if (other.batchSize!= null) {
return false;
}
} else {
if (!batchSize.equals(other.batchSize)) {
return false;
}
}
if (debugInfoOnStackTrace == null) {
if (other.debugInfoOnStackTrace!= null) {
return false;
@ -4066,6 +4103,7 @@ public class Settings
result = ((prime*result)+((queryTimeout == null)? 0 :queryTimeout.hashCode()));
result = ((prime*result)+((maxRows == null)? 0 :maxRows.hashCode()));
result = ((prime*result)+((fetchSize == null)? 0 :fetchSize.hashCode()));
result = ((prime*result)+((batchSize == null)? 0 :batchSize.hashCode()));
result = ((prime*result)+((debugInfoOnStackTrace == null)? 0 :debugInfoOnStackTrace.hashCode()));
result = ((prime*result)+((inListPadding == null)? 0 :inListPadding.hashCode()));
result = ((prime*result)+((inListPadBase == null)? 0 :inListPadBase.hashCode()));

View File

@ -387,6 +387,15 @@ public final class SettingsTools {
: 0;
}
/**
* Return the specified {@link Settings#getBatchSize()}.
*/
public static final int getBatchSize(Settings settings) {
return settings.getBatchSize() != null
? settings.getBatchSize()
: 0;
}
/**
* Return <code>fetchServerOutputSize</code> if it is not <code>0</code>, or
* the specified {@link Settings#getFetchServerOutputSize()}.

View File

@ -275,6 +275,7 @@ import org.jooq.WithAsStep8;
import org.jooq.WithAsStep9;
import org.jooq.WithStep;
import org.jooq.conf.Settings;
import org.jooq.conf.SettingsTools;
import org.jooq.exception.ConfigurationException;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.InvalidResultException;
@ -2817,7 +2818,7 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
return connectionResult(new ConnectionCallable<T>() {
@Override
public T run(Connection connection) throws Exception {
BatchedConnection bc = new BatchedConnection(connection);
BatchedConnection bc = new BatchedConnection(connection, SettingsTools.getBatchSize(settings()));
Configuration c = configuration().derive(bc);
try {

View File

@ -79,25 +79,32 @@ import java.util.regex.Pattern;
*/
public class BatchedConnection extends DefaultConnection {
String lastSQL;
PreparedStatement lastStatement;
final int batchSize;
String lastSQL;
BatchedPreparedStatement lastStatement;
public BatchedConnection(Connection delegate) {
this(delegate, Integer.MAX_VALUE);
}
public BatchedConnection(Connection delegate, int batchSize) {
super(delegate);
this.batchSize = batchSize;
}
// -------------------------------------------------------------------------
// XXX: Utilities
// -------------------------------------------------------------------------
private void executeLastBatch(String sql) throws SQLException {
void executeLastBatch(String sql) throws SQLException {
if (!sql.equals(lastSQL))
executeLastBatch();
}
private void executeLastBatch() throws SQLException {
void executeLastBatch() throws SQLException {
if (lastStatement != null) {
if (lastStatement instanceof BatchedPreparedStatement && ((BatchedPreparedStatement) lastStatement).batches > 0)
if (lastStatement.batches > 0)
lastStatement.executeBatch();
safeClose(lastStatement);
@ -188,7 +195,7 @@ public class BatchedConnection extends DefaultConnection {
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
executeLastBatch(sql);
return lastStatement != null ? lastStatement : (lastStatement = prepareStatement0(lastSQL = sql));
return lastStatement != null ? lastStatement : prepareStatement0(sql);
}
// TODO: Can we implement this in a more sophisticated way without invoking the costly parser?
@ -197,9 +204,12 @@ public class BatchedConnection extends DefaultConnection {
private PreparedStatement prepareStatement0(String sql) throws SQLException {
PreparedStatement result = super.prepareStatement(sql);
return P_DML.matcher(sql).matches()
? new BatchedPreparedStatement(this, result)
: result;
if (P_DML.matcher(sql).matches()) {
lastSQL = sql;
return lastStatement = new BatchedPreparedStatement(this, result);
}
else
return result;
}
// -------------------------------------------------------------------------

View File

@ -129,6 +129,9 @@ public class BatchedPreparedStatement extends DefaultPreparedStatement {
batches++;
logBatch();
super.addBatch();
if (batches >= getBatchedConnection().batchSize)
getBatchedConnection().executeLastBatch();
}
@Override

View File

@ -429,6 +429,10 @@ jOOQ queries, for which no specific maxRows value was specified.]]></jxb:javadoc
jOOQ queries, for which no specific fetchSize value was specified.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="batchSize" type="int" minOccurs="0" maxOccurs="1" default="2147483647">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A property specifying a batch size that should be applied to all automatically created {@link org.jooq.tools.jdbc.BatchedConnection} instances.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="debugInfoOnStackTrace" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#5570] Whether exception stack traces should be enhanced with additional debug information.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>