110 lines
3.6 KiB
Java
110 lines
3.6 KiB
Java
package com.moparisthebest.jdbc;
|
|
|
|
import com.moparisthebest.jdbc.codegen.JdbcMapper;
|
|
import com.moparisthebest.jdbc.codegen.JdbcMapperFactory;
|
|
import com.moparisthebest.jdbc.util.Bindable;
|
|
import com.moparisthebest.jdbc.util.InListUtil;
|
|
|
|
import java.lang.reflect.Method;
|
|
import java.sql.Connection;
|
|
import java.sql.SQLException;
|
|
import java.util.Collection;
|
|
|
|
/**
|
|
* For a column name and a Collection, return a Object usable by QueryMapper for binding to a PreparedStatement and
|
|
* ListQueryMapper for substituting in the query
|
|
*/
|
|
public interface InList {
|
|
|
|
InList defaultInList = InListObject.getDefaultInListInstance();
|
|
|
|
/**
|
|
* Returns an InList instance for use with this connection
|
|
* @param conn connection which may be inspected to determine best InList to use
|
|
* @return InList instance
|
|
*/
|
|
public InList instance(final Connection conn);
|
|
|
|
/**
|
|
* Returns an Object who's .toString returns a String for a query, and QueryMapper knows how to bind to a PreparedStatement
|
|
* @param columnName Column name for query
|
|
* @param values values for in list
|
|
* @return object
|
|
*/
|
|
public <T> InListObject inList(final Connection conn, final String columnName, final Collection<T> values) throws SQLException;
|
|
|
|
/**
|
|
* Returns an Object who's .toString returns a String for a query, and QueryMapper knows how to bind to a PreparedStatement
|
|
* @param columnName Column name for query
|
|
* @param values values for not in list
|
|
* @return object
|
|
*/
|
|
public <T> InListObject notInList(final Connection conn, final String columnName, final Collection<T> values) throws SQLException;
|
|
|
|
class InListObject implements Bindable {
|
|
static final InListObject inEmpty = new InListObject(InListUtil.inEmpty, null);
|
|
static final InListObject notInEmpty = new InListObject(InListUtil.notInEmpty, null);
|
|
|
|
public static InListObject inEmpty() {
|
|
return inEmpty;
|
|
}
|
|
|
|
public static InListObject notInEmpty() {
|
|
return notInEmpty;
|
|
}
|
|
|
|
private final String sql;
|
|
private final Object bindObject;
|
|
|
|
public InListObject(final String sql, final Object bindObject) {
|
|
this.sql = sql;
|
|
this.bindObject = bindObject;
|
|
}
|
|
|
|
@Override
|
|
public final String toString() {
|
|
return sql;
|
|
}
|
|
|
|
@Override
|
|
public Object getBindObject() {
|
|
return bindObject;
|
|
}
|
|
|
|
private static InList getDefaultInListInstance() {
|
|
try {
|
|
JdbcMapperFactory.connectionFactory(""); // need this so QueryMapper.ensureContext.class is called first in case it sets System properties used below
|
|
final String inListClassName = System.getProperty("QueryMapper.defaultInList.class");
|
|
if(inListClassName != null) {
|
|
final Class<?> inListClass = Class.forName(inListClassName);
|
|
final Method method = inListClass.getMethod(System.getProperty("QueryMapper.defaultInList.method", "instance"));
|
|
return (InList) method.invoke(null);
|
|
} else {
|
|
// todo: change default to OPTIMAL ?
|
|
final String type = System.getProperty("queryMapper.databaseType", System.getProperty("jdbcMapper.databaseType", "BIND"));
|
|
if(type.equals("OPTIMAL")) {
|
|
return OptimalInList.instance();
|
|
} else {
|
|
switch (JdbcMapper.DatabaseType.valueOf(type)) {
|
|
case DEFAULT:
|
|
case BIND:
|
|
return BindInList.instance();
|
|
case ANY:
|
|
return ArrayInList.instance();
|
|
case ORACLE:
|
|
return OracleArrayInList.instance();
|
|
case UNNEST:
|
|
return UnNestArrayInList.instance();
|
|
default:
|
|
throw new RuntimeException("Invalid queryMapper.databaseType: " + type);
|
|
}
|
|
}
|
|
}
|
|
} catch (Throwable e) {
|
|
// NEVER ignore
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
}
|
|
}
|