/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jdbi.v3.core.statement;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Stream;
import org.jdbi.v3.core.Handle;
import org.jdbi.v3.core.argument.Argument;
import org.jdbi.v3.core.argument.Arguments;
import org.jdbi.v3.core.argument.BeanPropertyArguments;
import org.jdbi.v3.core.argument.CharacterStreamArgument;
import org.jdbi.v3.core.argument.InputStreamArgument;
import org.jdbi.v3.core.argument.MapArguments;
import org.jdbi.v3.core.argument.NamedArgumentFinder;
import org.jdbi.v3.core.argument.NullArgument;
import org.jdbi.v3.core.argument.ObjectArgument;
import org.jdbi.v3.core.argument.ObjectFieldArguments;
import org.jdbi.v3.core.argument.ObjectMethodArguments;
import org.jdbi.v3.core.argument.internal.PojoPropertyArguments;
import org.jdbi.v3.core.generic.GenericType;
import org.jdbi.v3.core.mapper.Mappers;
import org.jdbi.v3.core.mapper.RowMapper;
import org.jdbi.v3.core.mapper.immutables.JdbiImmutables;
import org.jdbi.v3.core.qualifier.NVarchar;
import org.jdbi.v3.core.qualifier.QualifiedType;
import org.jdbi.v3.meta.Beta;
import static java.util.stream.Collectors.joining;
This class provides the common functions between Query
and
Update
. It defines most of the argument binding functions
used by its subclasses.
/**
* This class provides the common functions between <code>Query</code> and
* <code>Update</code>. It defines most of the argument binding functions
* used by its subclasses.
*/
@SuppressWarnings({"deprecation", "PMD.ExcessiveClassLength"})
public abstract class SqlStatement<This extends SqlStatement<This>> extends BaseStatement<This> {
private final Handle handle;
private final String sql;
PreparedStatement stmt;
SqlStatement(Handle handle,
String sql) {
super(handle);
this.handle = handle;
this.sql = sql;
getContext()
.setConnection(handle.getConnection())
.setRawSql(sql);
}
protected Binding getBinding() {
return getContext().getBinding();
}
Returns: the un-translated SQL used to create this statement
/**
* @return the un-translated SQL used to create this statement
*/
protected String getSql() {
return sql;
}
Set the query timeout, in seconds, on the prepared statement
Params: - seconds – number of seconds before timing out
Returns: the same Query instance
/**
* Set the query timeout, in seconds, on the prepared statement
*
* @param seconds number of seconds before timing out
*
* @return the same Query instance
*/
public This setQueryTimeout(final int seconds) {
return addCustomizer(StatementCustomizers.statementTimeout(seconds));
}
Transfer ownership of the handle to the statement: when the statement is closed,
commit the handle's transaction (if one exists) and close the handle.
Returns: this
/**
* Transfer ownership of the handle to the statement: when the statement is closed,
* commit the handle's transaction (if one exists) and close the handle.
* @return this
*/
public This cleanupHandleCommit() {
return cleanupHandle(Handle::commit);
}
When the statement is closed, roll it back then close the owning Handle.
Returns: this
/**
* When the statement is closed, roll it back then close the owning Handle.
* @return this
*/
public This cleanupHandleRollback() {
return cleanupHandle(Handle::rollback);
}
private This cleanupHandle(Consumer<Handle> action) {
addCleanable(() -> {
if (handle != null) {
if (handle.isInTransaction()) {
action.accept(handle);
}
handle.close();
}
});
return typedThis;
}
Used if you need to have some exotic parameter bound.
Params: - position – position to bindBinaryStream this argument, starting at 0
- argument – exotic argument factory
Returns: the same Query instance
/**
* Used if you need to have some exotic parameter bound.
*
* @param position position to bindBinaryStream this argument, starting at 0
* @param argument exotic argument factory
*
* @return the same Query instance
*/
@SuppressWarnings("unchecked")
public This bind(int position, Argument argument) {
getBinding().addPositional(position, argument);
return (This) this;
}
Used if you need to have some exotic parameter bound.
Params: - name – name to bindBinaryStream this argument
- argument – exotic argument factory
Returns: the same Query instance
/**
* Used if you need to have some exotic parameter bound.
*
* @param name name to bindBinaryStream this argument
* @param argument exotic argument factory
*
* @return the same Query instance
*/
public This bind(String name, Argument argument) {
getBinding().addNamed(name, argument);
return typedThis;
}
Binds named parameters from JavaBean properties on the argument.
Params: - bean – source of named parameter values to use as arguments
Returns: modified statement
/**
* Binds named parameters from JavaBean properties on the argument.
*
* @param bean source of named parameter values to use as arguments
*
* @return modified statement
*/
@SuppressWarnings("deprecation")
public This bindBean(Object bean) {
return bindNamedArgumentFinder(new BeanPropertyArguments(null, bean));
}
Binds named parameters from JavaBean properties on the bean argument, with the given prefix. Example: the prefix foo
applied to a bean property bar
will be bound as foo.bar
. Params: - prefix – a prefix to apply to all property names.
- bean – source of named parameter values to use as arguments
Returns: modified statement
/**
* Binds named parameters from JavaBean properties on the bean argument, with the given prefix.
*
* Example: the prefix {@code foo} applied to a bean property {@code bar} will be bound as {@code foo.bar}.
*
* @param prefix a prefix to apply to all property names.
* @param bean source of named parameter values to use as arguments
*
* @return modified statement
*/
@SuppressWarnings("deprecation")
public This bindBean(String prefix, Object bean) {
return bindNamedArgumentFinder(new BeanPropertyArguments(prefix, bean));
}
Binds named parameters from object properties on the argument.
The type must have been registered with pojo type mapping functionality first, usually
by a plugin or configuration.
Params: - pojo – source of named parameter values to use as arguments
See Also: Returns: modified statement
/**
* Binds named parameters from object properties on the argument.
* The type must have been registered with pojo type mapping functionality first, usually
* by a plugin or configuration.
*
* @param pojo source of named parameter values to use as arguments
*
* @return modified statement
* @see JdbiImmutables an example method of registering a type
*/
@Beta
public This bindPojo(Object pojo) {
return bindPojo(null, pojo);
}
Binds named parameters from object properties on the bean argument, with the given prefix.
The type must have been registered with pojo type mapping functionality first, usually
by a plugin or configuration.
Params: - prefix – a prefix to apply to all property names.
- pojo – source of named parameter values to use as arguments
See Also: Returns: modified statement
/**
* Binds named parameters from object properties on the bean argument, with the given prefix.
* The type must have been registered with pojo type mapping functionality first, usually
* by a plugin or configuration.
*
* @param prefix a prefix to apply to all property names.
* @param pojo source of named parameter values to use as arguments
*
* @return modified statement
* @see JdbiImmutables an example method of registering a type
*/
@Beta
public This bindPojo(String prefix, Object pojo) {
return bindNamedArgumentFinder(new PojoPropertyArguments(prefix, pojo, getConfig()));
}
Binds public fields of the specified object as arguments for the query.
Params: - object – source of the public fields to bind.
Returns: modified statement
/**
* Binds public fields of the specified object as arguments for the query.
*
* @param object source of the public fields to bind.
*
* @return modified statement
*/
public This bindFields(Object object) {
return bindNamedArgumentFinder(new ObjectFieldArguments(null, object));
}
Binds public fields of the specified object as arguments for the query.
Params: - prefix – a prefix to apply to all field names.
- object – source of the public fields to bind.
Returns: modified statement
/**
* Binds public fields of the specified object as arguments for the query.
*
* @param prefix a prefix to apply to all field names.
* @param object source of the public fields to bind.
*
* @return modified statement
*/
public This bindFields(String prefix, Object object) {
return bindNamedArgumentFinder(new ObjectFieldArguments(prefix, object));
}
Binds methods with no parameters on the argument.
Params: - object – source of methods to use as arguments
Returns: modified statement
/**
* Binds methods with no parameters on the argument.
*
* @param object source of methods to use as arguments
*
* @return modified statement
*/
public This bindMethods(Object object) {
return bindNamedArgumentFinder(new ObjectMethodArguments(null, object));
}
Binds methods with no parameters on the argument, with the given prefix.
Params: - prefix – a prefix to apply to all property names.
- object – source of methods to use as arguments
Returns: modified statement
/**
* Binds methods with no parameters on the argument, with the given prefix.
*
* @param prefix a prefix to apply to all property names.
* @param object source of methods to use as arguments
*
* @return modified statement
*/
public This bindMethods(String prefix, Object object) {
return bindNamedArgumentFinder(new ObjectMethodArguments(prefix, object));
}
Binds named parameters from a map of String to Object instances
Params: - map – map where keys are matched to named parameters in order to bind arguments.
Can be null, in which case the binding has no effect.
Returns: modified statement
/**
* Binds named parameters from a map of String to Object instances
*
* @param map map where keys are matched to named parameters in order to bind arguments.
* Can be null, in which case the binding has no effect.
*
* @return modified statement
*/
public This bindMap(Map<String, ?> map) {
return map == null ? typedThis : bindNamedArgumentFinder(new MapArguments(map));
}
Binds a new NamedArgumentFinder
. Params: - namedArgumentFinder – A NamedArgumentFinder to bind. Can be null.
Returns: the same Query instance
/**
* Binds a new {@link NamedArgumentFinder}.
*
* @param namedArgumentFinder A NamedArgumentFinder to bind. Can be null.
*
* @return the same Query instance
*/
public This bindNamedArgumentFinder(final NamedArgumentFinder namedArgumentFinder) {
if (namedArgumentFinder != null) {
getBinding().addNamedArgumentFinder(namedArgumentFinder);
}
return typedThis;
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Character value) {
return bind(position, toArgument(Character.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Character value) {
return bind(name, toArgument(Character.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, String value) {
return bind(position, toArgument(String.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, String value) {
return bind(name, toArgument(String.class, value));
}
Bind a String
argument positionally, as NVARCHAR
type. Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind a {@code String} argument positionally, as {@code NVARCHAR} type.
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
@Beta
public final This bindNVarchar(int position, String value) {
return bind(position, toArgument(QualifiedType.of(String.class).with(NVarchar.class), value));
}
Bind a String
argument by name, as NVARCHAR
type. Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind a {@code String} argument by name, as {@code NVARCHAR} type.
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
@Beta
public final This bindNVarchar(String name, String value) {
return bind(name, toArgument(QualifiedType.of(String.class).with(NVarchar.class), value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, int value) {
return bind(position, toArgument(int.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Integer value) {
return bind(position, toArgument(Integer.class, value));
}
Bind an argument by name
Params: - name – name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, int value) {
return bind(name, toArgument(int.class, value));
}
Bind an argument by name
Params: - name – name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Integer value) {
return bind(name, toArgument(Integer.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, char value) {
return bind(position, toArgument(char.class, value));
}
Bind an argument by name
Params: - name – name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, char value) {
return bind(name, toArgument(char.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
- length – how long is the stream being bound?
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
* @param length how long is the stream being bound?
*
* @return the same Query instance
*/
public final This bindASCIIStream(int position, InputStream value, int length) {
return bind(position, new InputStreamArgument(value, length, true));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
- length – bytes to read from value
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
* @param length bytes to read from value
*
* @return the same Query instance
*/
public final This bindASCIIStream(String name, InputStream value, int length) {
return bind(name, new InputStreamArgument(value, length, true));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, BigDecimal value) {
return bind(position, toArgument(BigDecimal.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, BigDecimal value) {
return bind(name, toArgument(BigDecimal.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
- length – the number of bytes in the stream.
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
* @param length the number of bytes in the stream.
*
* @return the same Query instance
*/
public final This bindBinaryStream(int position, InputStream value, int length) {
return bind(position, new InputStreamArgument(value, length, false));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
- length – bytes to read from value
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
* @param length bytes to read from value
*
* @return the same Query instance
*/
public final This bindBinaryStream(String name, InputStream value, int length) {
return bind(name, new InputStreamArgument(value, length, false));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Blob value) {
return bind(position, toArgument(Blob.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Blob value) {
return bind(name, toArgument(Blob.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, boolean value) {
return bind(position, toArgument(boolean.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Boolean value) {
return bind(position, toArgument(Boolean.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, boolean value) {
return bind(name, toArgument(boolean.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Boolean value) {
return bind(name, toArgument(Boolean.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, byte value) {
return bind(position, toArgument(byte.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Byte value) {
return bind(position, toArgument(Byte.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, byte value) {
return bind(name, toArgument(byte.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Byte value) {
return bind(name, toArgument(Byte.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, byte[] value) {
return bind(position, toArgument(byte[].class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, byte[] value) {
return bind(name, toArgument(byte[].class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
- length – number of characters to read
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
* @param length number of characters to read
*
* @return the same Query instance
*/
public final This bind(int position, Reader value, int length) {
return bind(position, new CharacterStreamArgument(value, length));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
- length – number of characters to read
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
* @param length number of characters to read
*
* @return the same Query instance
*/
public final This bind(String name, Reader value, int length) {
return bind(name, new CharacterStreamArgument(value, length));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Clob value) {
return bind(position, toArgument(Clob.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Clob value) {
return bind(name, toArgument(Clob.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, java.sql.Date value) {
return bind(position, toArgument(java.sql.Date.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, java.sql.Date value) {
return bind(name, toArgument(java.sql.Date.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, java.util.Date value) {
return bind(position, toArgument(java.util.Date.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, java.util.Date value) {
return bind(name, toArgument(java.util.Date.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, double value) {
return bind(position, toArgument(double.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Double value) {
return bind(position, toArgument(Double.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, double value) {
return bind(name, toArgument(double.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Double value) {
return bind(name, toArgument(Double.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, float value) {
return bind(position, toArgument(float.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Float value) {
return bind(position, toArgument(Float.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, float value) {
return bind(name, toArgument(float.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Float value) {
return bind(name, toArgument(Float.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, long value) {
return bind(position, toArgument(long.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Long value) {
return bind(position, toArgument(Long.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, long value) {
return bind(name, toArgument(long.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Long value) {
return bind(name, toArgument(Long.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Short value) {
return bind(position, toArgument(Short.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, short value) {
return bind(position, toArgument(short.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, short value) {
return bind(name, toArgument(short.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Short value) {
return bind(name, toArgument(short.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Object value) {
return bind(position, toArgument(value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Object value) {
return bind(name, toArgument(value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Time value) {
return bind(position, toArgument(Time.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Time value) {
return bind(name, toArgument(Time.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, Timestamp value) {
return bind(position, toArgument(Timestamp.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, Timestamp value) {
return bind(name, toArgument(Timestamp.class, value));
}
Bind an argument positionally
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
Returns: the same Query instance
/**
* Bind an argument positionally
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(int position, URL value) {
return bind(position, toArgument(URL.class, value));
}
Bind an argument by name
Params: - name – token name to bind the parameter to
- value – to bind
Returns: the same Query instance
/**
* Bind an argument by name
*
* @param name token name to bind the parameter to
* @param value to bind
*
* @return the same Query instance
*/
public final This bind(String name, URL value) {
return bind(name, toArgument(URL.class, value));
}
Bind an argument dynamically by the type passed in.
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
- argumentType – type for value argument
Returns: the same Query instance
/**
* Bind an argument dynamically by the type passed in.
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
* @param argumentType type for value argument
*
* @return the same Query instance
*/
public final This bindByType(int position, Object value, Type argumentType) {
return bind(position, toArgument(argumentType, value));
}
Bind an argument dynamically by the generic type passed in.
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
- argumentType – type token for value argument
Returns: the same Query instance
/**
* Bind an argument dynamically by the generic type passed in.
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
* @param argumentType type token for value argument
*
* @return the same Query instance
*/
public final This bindByType(int position, Object value, GenericType<?> argumentType) {
return bindByType(position, value, argumentType.getType());
}
Bind an argument dynamically by the qualified type passed in.
Params: - position – position to bind the parameter at, starting at 0
- value – to bind
- argumentType – type token for value argument
Returns: the same Query instance
/**
* Bind an argument dynamically by the qualified type passed in.
*
* @param position position to bind the parameter at, starting at 0
* @param value to bind
* @param argumentType type token for value argument
*
* @return the same Query instance
*/
@Beta
public final This bindByType(int position, Object value, QualifiedType<?> argumentType) {
return bind(position, toArgument(argumentType, value));
}
Bind an argument dynamically by the type passed in.
Params: - name – token name to bind the parameter to
- value – to bind
- argumentType – type for value argument
Returns: the same Query instance
/**
* Bind an argument dynamically by the type passed in.
*
* @param name token name to bind the parameter to
* @param value to bind
* @param argumentType type for value argument
*
* @return the same Query instance
*/
public final This bindByType(String name, Object value, Type argumentType) {
return bind(name, toArgument(argumentType, value));
}
Bind an argument dynamically by the generic type passed in.
Params: - name – token name to bind the parameter to
- value – to bind
- argumentType – type token for value argument
Returns: the same Query instance
/**
* Bind an argument dynamically by the generic type passed in.
*
* @param name token name to bind the parameter to
* @param value to bind
* @param argumentType type token for value argument
*
* @return the same Query instance
*/
public final This bindByType(String name, Object value, GenericType<?> argumentType) {
return bindByType(name, value, argumentType.getType());
}
Bind an argument dynamically by the type passed in.
Params: - name – token name to bind the parameter to
- value – to bind
- argumentType – type for value argument
Returns: the same Query instance
/**
* Bind an argument dynamically by the type passed in.
*
* @param name token name to bind the parameter to
* @param value to bind
* @param argumentType type for value argument
*
* @return the same Query instance
*/
@Beta
public final This bindByType(String name, Object value, QualifiedType<?> argumentType) {
return bind(name, toArgument(argumentType, value));
}
private Argument toArgument(Object value) {
return toArgument(value == null ? Object.class : value.getClass(), value);
}
private Argument toArgument(Type type, Object value) {
Argument arg = getConfig(Arguments.class).findFor(type, value)
.orElseThrow(() -> factoryNotFound(type, value));
try {
boolean toStringIsImplementedInArgument = arg.getClass().getMethod("toString").getDeclaringClass() != Object.class;
if (toStringIsImplementedInArgument) {
return arg;
} else {
return new Argument() {
@Override
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
arg.apply(position, statement, ctx);
}
@Override
public String toString() {
return Objects.toString(value);
}
};
}
} catch (NoSuchMethodException e) {
throw new Error("toString method does not exist, Object hierarchy is corrupt", e);
}
}
private Argument toArgument(QualifiedType<?> type, Object value) {
return getConfig(Arguments.class).findFor(type, value)
.orElseThrow(() -> factoryNotFound(type, value));
}
private UnsupportedOperationException factoryNotFound(Type type, Object value) {
if (type instanceof Class<?>) { // not a ParameterizedType
final TypeVariable<?>[] params = ((Class<?>) type).getTypeParameters();
if (params.length > 0) {
return new UnsupportedOperationException("No type parameters found for erased type '" + type + Arrays.toString(params)
+ "'. To bind a generic type, prefer using bindByType.");
}
}
return new UnsupportedOperationException("No argument factory registered for '" + value + "' of type " + type);
}
private UnsupportedOperationException factoryNotFound(QualifiedType<?> qualifiedType, Object value) {
Type type = qualifiedType.getType();
if (type instanceof Class<?>) { // not a ParameterizedType
final TypeVariable<?>[] params = ((Class<?>) type).getTypeParameters();
if (params.length > 0) {
return new UnsupportedOperationException("No type parameters found for erased type '" + type + Arrays.toString(params)
+ "' with qualifiers '" + qualifiedType.getQualifiers()
+ "'. To bind a generic type, prefer using bindByType.");
}
}
return new UnsupportedOperationException("No argument factory registered for '" + value + "' of qualified type " + qualifiedType);
}
Bind NULL to be set for a given argument.
Params: - name – Named parameter to bind to
- sqlType – The sqlType must be set and is a value from
java.sql.Types
Returns: the same statement instance
/**
* Bind NULL to be set for a given argument.
*
* @param name Named parameter to bind to
* @param sqlType The sqlType must be set and is a value from <code>java.sql.Types</code>
*
* @return the same statement instance
*/
public final This bindNull(String name, int sqlType) {
return bind(name, new NullArgument(sqlType));
}
Bind NULL to be set for a given argument.
Params: - position – position to bind NULL to, starting at 0
- sqlType – The sqlType must be set and is a value from
java.sql.Types
Returns: the same statement instance
/**
* Bind NULL to be set for a given argument.
*
* @param position position to bind NULL to, starting at 0
* @param sqlType The sqlType must be set and is a value from <code>java.sql.Types</code>
*
* @return the same statement instance
*/
public final This bindNull(int position, int sqlType) {
return bind(position, new NullArgument(sqlType));
}
Bind a value using a specific type from java.sql.Types
via
PreparedStatement#setObject(int, Object, int)
Params: - name – Named parameter to bind at
- value – Value to bind
- sqlType – The sqlType from java.sql.Types
Returns: self
/**
* Bind a value using a specific type from <code>java.sql.Types</code> via
* PreparedStatement#setObject(int, Object, int)
*
* @param name Named parameter to bind at
* @param value Value to bind
* @param sqlType The sqlType from java.sql.Types
*
* @return self
*/
public final This bindBySqlType(String name, Object value, int sqlType) {
return bind(name, ObjectArgument.of(value, sqlType));
}
Bind a value using a specific type from java.sql.Types
via
PreparedStatement#setObject(int, Object, int)
Params: - position – position to bind NULL to, starting at 0
- value – Value to bind
- sqlType – The sqlType from java.sql.Types
Returns: self
/**
* Bind a value using a specific type from <code>java.sql.Types</code> via
* PreparedStatement#setObject(int, Object, int)
*
* @param position position to bind NULL to, starting at 0
* @param value Value to bind
* @param sqlType The sqlType from java.sql.Types
*
* @return self
*/
public final This bindBySqlType(int position, Object value, int sqlType) {
return bind(position, ObjectArgument.of(value, sqlType));
}
Bind a parameter for each value in the given vararg array, and defines an attribute as the comma-separated list
of parameter references (using colon prefix).
Examples:
handle.createUpdate("insert into things (<columnNames>) values (<values>)")
.defineList("columnNames", "id", "name", "created_on")
.bindList("values", 1, "Alice", LocalDate.now())
.execute();
List<Thing> things = handle.createQuery("select * from things where id in (<ids>)")
.bindList("ids", 1, 2, 3)
.mapTo(Contact.class)
.list();
Params: - key – attribute name
- values – vararg values that will be comma-spliced into the defined attribute value.
Throws: - IllegalArgumentException – if the vararg array is empty.
Returns: this
/**
* Bind a parameter for each value in the given vararg array, and defines an attribute as the comma-separated list
* of parameter references (using colon prefix).
* <p>
* Examples:
* <pre>
* handle.createUpdate("insert into things (<columnNames>) values (<values>)")
* .defineList("columnNames", "id", "name", "created_on")
* .bindList("values", 1, "Alice", LocalDate.now())
* .execute();
*
* List<Thing> things = handle.createQuery("select * from things where id in (<ids>)")
* .bindList("ids", 1, 2, 3)
* .mapTo(Contact.class)
* .list();
* </pre>
*
* @param key attribute name
* @param values vararg values that will be comma-spliced into the defined attribute value.
* @return this
* @throws IllegalArgumentException if the vararg array is empty.
*/
public final This bindList(String key, Object... values) {
if (values.length == 0) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".bindList was called with no vararg values.");
}
return bindList(key, Arrays.asList(values));
}
Bind a parameter for each value in the given list, and defines an attribute as the comma-separated list of
parameter references (using colon prefix).
Examples:
List<String> columnNames = Arrays.asList("id", "name", "created_on");
List<Object> values = Arrays.asList(1, "Alice", LocalDate.now());
handle.createUpdate("insert into things (<columnNames>) values (<values>)")
.defineList("columnNames", columnNames)
.bindList("values", values)
.execute();
List<Integer> ids = Arrays.asList(1, 2, 3);
List<Thing> things = handle.createQuery("select * from things where id in (<ids>)")
.bindList("ids", ids)
.mapTo(Contact.class)
.list();
Params: - key – attribute name
- values – list of values that will be comma-spliced into the defined attribute value.
Throws: - IllegalArgumentException – if the list is empty.
Returns: this
/**
* Bind a parameter for each value in the given list, and defines an attribute as the comma-separated list of
* parameter references (using colon prefix).
* <p>
* Examples:
* <pre>
* List<String> columnNames = Arrays.asList("id", "name", "created_on");
* List<Object> values = Arrays.asList(1, "Alice", LocalDate.now());
* handle.createUpdate("insert into things (<columnNames>) values (<values>)")
* .defineList("columnNames", columnNames)
* .bindList("values", values)
* .execute();
*
* List<Integer> ids = Arrays.asList(1, 2, 3);
* List<Thing> things = handle.createQuery("select * from things where id in (<ids>)")
* .bindList("ids", ids)
* .mapTo(Contact.class)
* .list();
* </pre>
*
* @param key attribute name
* @param values list of values that will be comma-spliced into the defined attribute value.
* @return this
* @throws IllegalArgumentException if the list is empty.
*/
public final This bindList(String key, List<?> values) {
if (values.isEmpty()) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".bindList was called with an empty list.");
}
StringBuilder names = new StringBuilder();
for (int i = 0; i < values.size(); i++) {
String name = "__" + key + "_" + i;
if (i > 0) {
names.append(',');
}
String paramName = getConfig().get(SqlStatements.class).getSqlParser().nameParameter(name, getContext());
names.append(paramName);
bind(name, values.get(i));
}
return define(key, names.toString());
}
Bind a parameter for each value in the given list * number of property names,
and defines an attribute as the comma-separated list of parameter references (using colon prefix).
Used to create query similar to:
select * from things where (id, foo) in ((1,'abc'),(2,'def'),(3,'ghi'))
Examples:
List<ThingKey> thingKeys = ...
List<Thing> things = handle.createQuery("select * from things where (id, foo) in (<thingKeys>)")
.bindBeanList("thingKeys", thingKeys, Arrays.asList("id", "foo"))
.mapTo(Contact.class)
.list();
Params: - key – attribute name
- values – list of values that will be comma-spliced into the defined attribute value.
- propertyNames – list of properties that will be invoked on the values.
Throws: - IllegalArgumentException – if the list of values or properties is empty.
- UnableToCreateStatementException – If a property can't be found on an value or we can't find a Argument for it.
Returns: this
/**
* Bind a parameter for each value in the given list * number of property names,
* and defines an attribute as the comma-separated list of parameter references (using colon prefix).
*
* Used to create query similar to:
* select * from things where (id, foo) in ((1,'abc'),(2,'def'),(3,'ghi'))
* <p>
* Examples:
* <pre>
*
* List<ThingKey> thingKeys = ...
* List<Thing> things = handle.createQuery("select * from things where (id, foo) in (<thingKeys>)")
* .bindBeanList("thingKeys", thingKeys, Arrays.asList("id", "foo"))
* .mapTo(Contact.class)
* .list();
* </pre>
*
* @param key attribute name
* @param values list of values that will be comma-spliced into the defined attribute value.
* @param propertyNames list of properties that will be invoked on the values.
* @return this
* @throws IllegalArgumentException if the list of values or properties is empty.
* @throws UnableToCreateStatementException If a property can't be found on an value or we can't find a Argument for it.
*/
public final This bindBeanList(String key, List<?> values, List<String> propertyNames) throws UnableToCreateStatementException {
if (values.isEmpty()) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".bindBeanList was called with no values.");
}
if (propertyNames.isEmpty()) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".bindBeanList was called with no properties.");
}
StringBuilder names = new StringBuilder();
StatementContext ctx = getContext();
for (int valueIndex = 0; valueIndex < values.size(); valueIndex++) {
if (valueIndex > 0) {
names.append(',');
}
Object bean = values.get(valueIndex);
BeanPropertyArguments beanProperties = new BeanPropertyArguments(null, bean);
names.append('(');
for (int propertyIndex = 0; propertyIndex < propertyNames.size(); propertyIndex++) {
if (propertyIndex > 0) {
names.append(',');
}
String propertyName = propertyNames.get(propertyIndex);
String name = "__" + key + '_' + valueIndex + '_' + propertyName;
names.append(':').append(name);
Argument argument = beanProperties.find(propertyName, ctx)
.orElseThrow(() -> new UnableToCreateStatementException("Unable to get " + propertyName + " argument for " + bean, ctx));
bind(name, argument);
}
names.append(')');
}
return define(key, names.toString());
}
For each value given, create a tuple by invoking each given method in order, and bind the tuple into a VALUES (...)
format insert clause. Params: - key – attribute name
- values – list of values that will be comma-spliced into the defined attribute value
- methodNames – list of methods that will be invoked on the values
Throws: - IllegalArgumentException – if the list of values or properties is empty.
- UnableToCreateStatementException – if the method cannot be found
Returns: this
/**
* For each value given, create a tuple by invoking each given method in order, and bind the tuple into
* a {@code VALUES (...)} format insert clause.
* @param key attribute name
* @param values list of values that will be comma-spliced into the defined attribute value
* @param methodNames list of methods that will be invoked on the values
* @return this
* @throws IllegalArgumentException if the list of values or properties is empty.
* @throws UnableToCreateStatementException if the method cannot be found
*/
public final This bindMethodsList(String key, Iterable<?> values, List<String> methodNames) throws UnableToCreateStatementException {
final Iterator<?> valueIter = values.iterator();
if (!valueIter.hasNext()) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".bindMethodsList was called with no values.");
}
if (methodNames.isEmpty()) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".bindMethodsList was called with no values.");
}
final StringBuilder names = new StringBuilder();
final StatementContext ctx = getContext();
for (int valueIndex = 0; valueIter.hasNext(); valueIndex++) {
if (valueIndex > 0) {
names.append(',');
}
final Object bean = valueIter.next();
final ObjectMethodArguments beanMethods = new ObjectMethodArguments(null, bean);
names.append('(');
for (int methodIndex = 0; methodIndex < methodNames.size(); methodIndex++) {
if (methodIndex > 0) {
names.append(',');
}
final String methodName = methodNames.get(methodIndex);
final String name = key + valueIndex + '.' + methodName;
names.append(':').append(name);
final Argument argument = beanMethods.find(methodName, ctx)
.orElseThrow(() -> new UnableToCreateStatementException("Unable to get " + methodName + " argument for " + bean, ctx));
bind(name, argument);
}
names.append(')');
}
return define(key, names.toString());
}
Define an attribute as the comma-separated String
from the elements of the values
argument.
Examples:
handle.createUpdate("insert into things (<columnNames>) values (<values>)")
.defineList("columnNames", "id", "name", "created_on")
.bindList("values", 1, "Alice", LocalDate.now())
.execute();
List<Thing> things = handle.createQuery("select <columnNames> from things")
.bindList("columnNames", "id", "name", "created_on")
.mapTo(Contact.class)
.list();
Params: - key – attribute name
- values – vararg values that will be comma-spliced into the defined attribute value.
Throws: - IllegalArgumentException – if the vararg array is empty, or contains any null elements.
Returns: this
/**
* Define an attribute as the comma-separated {@link String} from the elements of the {@code values} argument.
* <p>
* Examples:
* <pre>
* handle.createUpdate("insert into things (<columnNames>) values (<values>)")
* .defineList("columnNames", "id", "name", "created_on")
* .bindList("values", 1, "Alice", LocalDate.now())
* .execute();
*
* List<Thing> things = handle.createQuery("select <columnNames> from things")
* .bindList("columnNames", "id", "name", "created_on")
* .mapTo(Contact.class)
* .list();
* </pre>
*
* @param key attribute name
* @param values vararg values that will be comma-spliced into the defined attribute value.
* @return this
* @throws IllegalArgumentException if the vararg array is empty, or contains any null elements.
*/
public final This defineList(String key, Object... values) {
if (values.length == 0) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".defineList was called with no vararg values.");
}
if (Stream.of(values).anyMatch(Objects::isNull)) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".defineList was called with a vararg array containing null values.");
}
return defineList(key, Arrays.asList(values));
}
Define an attribute as the comma-separated String
from the elements of the values
argument.
Examples:
List<String> columnNames = Arrays.asList("id", "name", "created_on");
List<Object> values = Arrays.asList(1, "Alice", LocalDate.now());
handle.createUpdate("insert into things (<columnNames>) values (<values>)")
.defineList("columnNames", columnNames)
.bindList("values", 1, values)
.execute();
List<String> columnNames = Arrays.asList("id", "name", "created_on");
List<Thing> things = handle.createQuery("select <columnNames> from things")
.bindList("columnNames", columnNames)
.mapTo(Contact.class)
.list();
Params: - key – attribute name
- values – list of values that will be comma-spliced into the defined attribute value.
Throws: - IllegalArgumentException – if the list is empty, or contains any null elements.
Returns: this
/**
* Define an attribute as the comma-separated {@link String} from the elements of the {@code values} argument.
* <p>
* Examples:
* <pre>
* List<String> columnNames = Arrays.asList("id", "name", "created_on");
* List<Object> values = Arrays.asList(1, "Alice", LocalDate.now());
* handle.createUpdate("insert into things (<columnNames>) values (<values>)")
* .defineList("columnNames", columnNames)
* .bindList("values", 1, values)
* .execute();
*
* List<String> columnNames = Arrays.asList("id", "name", "created_on");
* List<Thing> things = handle.createQuery("select <columnNames> from things")
* .bindList("columnNames", columnNames)
* .mapTo(Contact.class)
* .list();
* </pre>
*
* @param key attribute name
* @param values list of values that will be comma-spliced into the defined attribute value.
* @return this
* @throws IllegalArgumentException if the list is empty, or contains any null elements.
*/
public final This defineList(String key, List<?> values) {
if (values.isEmpty()) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".defineList was called with an empty list.");
}
// Uses stream match, cause the Java 9 ImmutableList implementation throws an NPE if asked `contains(null)`
if (values.stream().anyMatch(Objects::isNull)) {
throw new IllegalArgumentException(
getClass().getSimpleName() + ".defineList was called with a list containing null values.");
}
String value = values.stream()
.map(Object::toString)
.collect(joining(", "));
return define(key, value);
}
Define all bound arguments that don't already have a definition with a boolean indicating their presence. Useful to easily template optional properties of pojos or beans like <if(property)>property = :property<endif>
. Returns: this
/**
* Define all bound arguments that don't already have a definition with a boolean indicating their presence.
* Useful to easily template optional properties of pojos or beans like {@code <if(property)>property = :property<endif>}.
* @return this
*/
@Beta
public This defineNamedBindings() {
return addCustomizer(new DefineNamedBindingsStatementCustomizer());
}
PreparedStatement internalExecute() {
final StatementContext ctx = getContext();
beforeTemplating();
String renderedSql = getConfig(SqlStatements.class)
.getTemplateEngine()
.render(sql, ctx);
ctx.setRenderedSql(renderedSql);
ParsedSql parsedSql = getConfig(SqlStatements.class)
.getSqlParser()
.parse(renderedSql, ctx);
String sql = parsedSql.getSql();
ctx.setParsedSql(parsedSql);
try {
if (getClass().isAssignableFrom(Call.class)) {
stmt = handle.getStatementBuilder().createCall(handle.getConnection(), sql, ctx);
} else {
stmt = handle.getStatementBuilder().create(handle.getConnection(), sql, ctx);
}
// The statement builder might (or might not) clean up the statement when called. E.g. the
// caching statement builder relies on the statement *not* being closed.
addCleanable(() -> handle.getStatementBuilder().close(handle.getConnection(), this.sql, stmt));
getConfig(SqlStatements.class).customize(stmt);
} catch (SQLException e) {
throw new UnableToCreateStatementException(e, ctx);
}
ctx.setStatement(stmt);
beforeBinding();
ArgumentBinder.bind(parsedSql.getParameters(), getBinding(), stmt, ctx);
beforeExecution();
try {
SqlLoggerUtil.wrap(stmt::execute, ctx, getConfig(SqlStatements.class).getSqlLogger());
} catch (SQLException e) {
try {
stmt.close();
} catch (SQLException e1) {
e.addSuppressed(e1);
}
throw new UnableToExecuteStatementException(e, ctx);
}
afterExecution();
return stmt;
}
@SuppressWarnings("unchecked")
<T> RowMapper<T> mapperForType(Class<T> type) {
return (RowMapper<T>) mapperForType((Type) type);
}
@SuppressWarnings("unchecked")
<T> RowMapper<T> mapperForType(GenericType<T> type) {
return (RowMapper<T>) mapperForType(type.getType());
}
RowMapper<?> mapperForType(Type type) {
return getConfig(Mappers.class).findFor(type)
.orElseThrow(() -> new UnsupportedOperationException("No mapper registered for " + type));
}
void beforeTemplating() {
callCustomizers(c -> c.beforeTemplating(stmt, getContext()));
}
void beforeBinding() {
callCustomizers(c -> c.beforeBinding(stmt, getContext()));
}
void beforeExecution() {
callCustomizers(c -> c.beforeExecution(stmt, getContext()));
}
void afterExecution() {
callCustomizers(c -> c.afterExecution(stmt, getContext()));
}
}