[#3973] Add better support for re-using named bind values

This commit is contained in:
lukaseder 2015-01-20 14:11:51 +01:00
parent 308dd68691
commit 9abd23a916
2 changed files with 99 additions and 10 deletions

View File

@ -41,6 +41,7 @@
package org.jooq;
import java.sql.Statement;
import java.util.Map;
/**
* This type is used for the {@link Batch}'s DSL API.
@ -54,14 +55,56 @@ import java.sql.Statement;
public interface BatchBindStep extends Batch {
/**
* Set bind values on the batch statement.
* Set indexed bind values onto the batch statement.
* <p>
* The argument array of <code>bindValues</code> will be set onto the
* indexed bind values of the batch statement:
* <ul>
* <li><code>:1</code> -> <code>bindValues[0]</code></li>
* <li><code>:2</code> -> <code>bindValues[1]</code></li>
* <li>...</li>
* <li><code>:N</code> -> <code>bindValues[N - 1]</code></li>
* </ul>
* <p>
* "Unmatched" bind values will be left unmodified:
* <ul>
* <li><code>:N+1</code> -> unmodified</li>
* <li><code>:N+2</code> -> unmodified</li>
* </ul>
*/
BatchBindStep bind(Object... bindValues);
/**
* Set several bind values on the batch statement.
* Set several indexed bind values onto the batch statement.
* <p>
* This is the same as calling {@link #bind(Object...)} several times.
*/
BatchBindStep bind(Object[][] bindValues);
BatchBindStep bind(Object[]... bindValues);
/**
* Set named bind values onto the batch statement.
* <p>
* The argument map of <code>namedBindValues</code> will be set onto the
* named bind values of the batch statement:
* <ul>
* <li><code>:name1</code> -> <code>bindValues.get("name1")</code></li>
* <li><code>:name2</code> -> <code>bindValues.get("name2")</code></li>
* <li>...</li>
* <li><code>:nameN</code> -> <code>bindValues.get("nameN")</code></li>
* </ul>
* <p>
* "Unmatched" bind values will be left unmodified:
* <ul>
* <li><code>:nameN+1</code> -> unmodified</li>
* <li><code>:nameN+2</code> -> unmodified</li>
* </ul>
*/
BatchBindStep bind(Map<String, Object> namedBindValues);
/**
* Set several named bind values onto the batch statement.
* <p>
* This is the same as calling {@link #bind(Map...)} several times.
*/
BatchBindStep bind(Map<String, Object>... namedBindValues);
}

View File

@ -49,7 +49,10 @@ import static org.jooq.impl.Utils.visitAll;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.jooq.BatchBindStep;
import org.jooq.Configuration;
@ -58,6 +61,7 @@ import org.jooq.DataType;
import org.jooq.ExecuteContext;
import org.jooq.ExecuteListener;
import org.jooq.Field;
import org.jooq.Param;
import org.jooq.Query;
import org.jooq.exception.ControlFlowSignal;
@ -69,18 +73,32 @@ class BatchSingle implements BatchBindStep {
/**
* Generated UID
*/
private static final long serialVersionUID = 3793967258181493207L;
private static final long serialVersionUID = 3793967258181493207L;
private final DSLContext create;
private final Configuration configuration;
private final Query query;
private final List<Object[]> allBindValues;
private final DSLContext create;
private final Configuration configuration;
private final Query query;
private final Map<String, List<Integer>> nameToIndexMapping;
private final List<Object[]> allBindValues;
public BatchSingle(Configuration configuration, Query query) {
this.create = DSL.using(configuration);
this.configuration = configuration;
this.query = query;
this.allBindValues = new ArrayList<Object[]>();
this.nameToIndexMapping = new LinkedHashMap<String, List<Integer>>();
int i = 0;
for (Entry<String, Param<?>> entry : query.getParams().entrySet()) {
List<Integer> list = nameToIndexMapping.get(entry.getKey());
if (list == null) {
list = new ArrayList<Integer>();
nameToIndexMapping.put(entry.getKey(), list);
}
list.add(i++);
}
}
@Override
@ -90,11 +108,39 @@ class BatchSingle implements BatchBindStep {
}
@Override
public final BatchSingle bind(Object[][] bindValues) {
for (Object[] v : bindValues) {
public final BatchSingle bind(Object[]... bindValues) {
for (Object[] v : bindValues)
bind(v);
return this;
}
@SuppressWarnings("unchecked")
@Override
public final BatchSingle bind(Map<String, Object> namedBindValues) {
return bind(new Map[] { namedBindValues });
}
@Override
public final BatchSingle bind(Map<String, Object>... namedBindValues) {
List<Object> defaultValues = query.getBindValues();
Object[][] bindValues = new Object[namedBindValues.length][];
for (int row = 0; row < bindValues.length; row++) {
bindValues[row] = defaultValues.toArray();
for (Entry<String, Object> entry : namedBindValues[row].entrySet()) {
List<Integer> indexes = nameToIndexMapping.get(entry.getKey());
if (indexes != null) {
for (int index : indexes) {
bindValues[row][index] = entry.getValue();
}
}
}
}
bind(bindValues);
return this;
}