mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-11-24 18:02:18 -05:00
First go at QueryRunner and Factory<Connection> arg for QueryMapper
This commit is contained in:
parent
09c114e106
commit
a22109f31c
10
common/src/main/java/com/moparisthebest/jdbc/Factory.java
Normal file
10
common/src/main/java/com/moparisthebest/jdbc/Factory.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.moparisthebest.jdbc;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 7/1/17.
|
||||||
|
*/
|
||||||
|
public interface Factory<T> {
|
||||||
|
T create() throws SQLException;
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.moparisthebest.jdbc;
|
||||||
|
|
||||||
|
import com.moparisthebest.jdbc.codegen.JdbcMapper;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/30/17.
|
||||||
|
*/
|
||||||
|
public class QueryRunner<T extends JdbcMapper> {
|
||||||
|
|
||||||
|
private final Factory<T> factory;
|
||||||
|
|
||||||
|
public QueryRunner(final Factory<T> factory) {
|
||||||
|
if(factory == null)
|
||||||
|
throw new NullPointerException("factory must be non-null");
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> E run(final Runner<T, E> query) throws SQLException {
|
||||||
|
if(query == null)
|
||||||
|
throw new NullPointerException("query must be non-null");
|
||||||
|
T dao = null;
|
||||||
|
try {
|
||||||
|
dao = factory.create();
|
||||||
|
return query.run(dao);
|
||||||
|
} finally {
|
||||||
|
tryClose(dao);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> E runInTransaction(final Runner<T, E> query) throws SQLException {
|
||||||
|
if(query == null)
|
||||||
|
throw new NullPointerException("query must be non-null");
|
||||||
|
T dao = null;
|
||||||
|
try {
|
||||||
|
dao = factory.create();
|
||||||
|
dao.getConnection().setAutoCommit(false);
|
||||||
|
final E ret = query.run(dao);
|
||||||
|
dao.getConnection().commit();
|
||||||
|
return ret;
|
||||||
|
} catch (final Throwable e) {
|
||||||
|
if (dao != null) {
|
||||||
|
try {
|
||||||
|
dao.getConnection().rollback();
|
||||||
|
} catch(SQLException excep) {
|
||||||
|
// ignore to throw original
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(e instanceof SQLException)
|
||||||
|
throw (SQLException) e;
|
||||||
|
if(e instanceof RuntimeException)
|
||||||
|
throw (RuntimeException) e;
|
||||||
|
throw new RuntimeException("odd error should never happen", e);
|
||||||
|
} finally {
|
||||||
|
if (dao != null) {
|
||||||
|
try {
|
||||||
|
dao.getConnection().setAutoCommit(true);
|
||||||
|
} catch(SQLException excep) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
tryClose(dao);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface Runner<T, E> {
|
||||||
|
E run(T dao) throws SQLException;
|
||||||
|
}
|
||||||
|
}
|
@ -1,24 +1,107 @@
|
|||||||
package com.moparisthebest.jdbc.codegen;
|
package com.moparisthebest.jdbc.codegen;
|
||||||
|
|
||||||
|
import com.moparisthebest.jdbc.Factory;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mopar on 5/24/17.
|
* Created by mopar on 5/24/17.
|
||||||
*/
|
*/
|
||||||
public abstract class JdbcMapperFactory {
|
public class JdbcMapperFactory<T> implements Factory<T> {
|
||||||
|
|
||||||
static final String SUFFIX = "Bean";
|
static final String SUFFIX = "Bean";
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> Class<? extends T> getImplementationClass(final Class<T> jdbcMapper) throws ClassNotFoundException {
|
||||||
|
return (Class<? extends T>) Class.forName(jdbcMapper.getName() + SUFFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Constructor<? extends T> getConnectionConstructor(final Class<T> jdbcMapper) throws ClassNotFoundException, NoSuchMethodException {
|
||||||
|
return getImplementationClass(jdbcMapper).getConstructor(Connection.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Constructor<? extends T> getDefaultConstructor(final Class<T> jdbcMapper) throws ClassNotFoundException, NoSuchMethodException {
|
||||||
|
return getImplementationClass(jdbcMapper).getConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Constructor<? extends T> getFactoryConstructor(final Class<T> jdbcMapper) throws ClassNotFoundException, NoSuchMethodException {
|
||||||
|
return getImplementationClass(jdbcMapper).getConstructor(Factory.class);
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> T create(final Class<T> jdbcMapper, final Connection connection) {
|
public static <T> T create(final Class<T> jdbcMapper, final Connection connection) {
|
||||||
try {
|
try {
|
||||||
return (T) Class.forName(jdbcMapper.getName() + SUFFIX).getConstructor(Connection.class).newInstance(connection);
|
return getConnectionConstructor(jdbcMapper).newInstance(connection);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T create(final Class<T> jdbcMapper) {
|
public static <T> T create(final Class<T> jdbcMapper) {
|
||||||
return create(jdbcMapper, null);
|
try {
|
||||||
|
return getDefaultConstructor(jdbcMapper).newInstance();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Constructor<? extends T> constructor;
|
||||||
|
private final Object[] args;
|
||||||
|
|
||||||
|
public JdbcMapperFactory(final Class<T> jdbcMapper) {
|
||||||
|
try {
|
||||||
|
this.constructor = getDefaultConstructor(jdbcMapper);
|
||||||
|
this.args = null;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JdbcMapperFactory(final Constructor<? extends T> constructor, final Object... args) {
|
||||||
|
if(constructor == null)
|
||||||
|
throw new NullPointerException("constructor must be non-null");
|
||||||
|
this.constructor = constructor;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JdbcMapperFactory(final Class<T> queryMapperClass, final Factory<Connection> connectionFactory) {
|
||||||
|
if(queryMapperClass == null)
|
||||||
|
throw new NullPointerException("queryMapperClass must be non-null");
|
||||||
|
if(connectionFactory == null)
|
||||||
|
throw new NullPointerException("connectionFactory must be non-null");
|
||||||
|
try {
|
||||||
|
this.constructor = queryMapperClass.getConstructor(Factory.class);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException("queryMapperClass must have a constructor that takes Factory<Connection>", e);
|
||||||
|
}
|
||||||
|
this.args = new Object[]{connectionFactory};
|
||||||
|
}
|
||||||
|
|
||||||
|
public JdbcMapperFactory(final Class<T> queryMapperClass, final String jndiName) {
|
||||||
|
if(queryMapperClass == null)
|
||||||
|
throw new NullPointerException("queryMapperClass must be non-null");
|
||||||
|
if(jndiName == null)
|
||||||
|
throw new NullPointerException("jndiName must be non-null");
|
||||||
|
try {
|
||||||
|
this.constructor = queryMapperClass.getConstructor(String.class);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException("queryMapperClass must have a constructor that takes String", e);
|
||||||
|
}
|
||||||
|
this.args = new Object[]{jndiName};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T create() throws SQLException {
|
||||||
|
try {
|
||||||
|
return this.constructor.newInstance(args);
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import java.time.*;
|
|||||||
* Created by mopar on 5/24/17.
|
* Created by mopar on 5/24/17.
|
||||||
*/
|
*/
|
||||||
@JdbcMapper.Mapper(
|
@JdbcMapper.Mapper(
|
||||||
// jndiName = "bob",
|
jndiName = "bob",
|
||||||
// databaseType = JdbcMapper.DatabaseType.ORACLE
|
// databaseType = JdbcMapper.DatabaseType.ORACLE
|
||||||
cachePreparedStatements = JdbcMapper.OptionalBool.FALSE
|
cachePreparedStatements = JdbcMapper.OptionalBool.FALSE
|
||||||
// , sqlParser = SimpleSQLParser.class
|
// , sqlParser = SimpleSQLParser.class
|
||||||
|
@ -22,8 +22,8 @@ public class CachingQueryMapper extends QueryMapper {
|
|||||||
|
|
||||||
protected final Map<String, PreparedStatement> cache;
|
protected final Map<String, PreparedStatement> cache;
|
||||||
|
|
||||||
protected CachingQueryMapper(Connection conn, String jndiName, ResultSetMapper cm, final int maxEntries) {
|
protected CachingQueryMapper(Connection conn, String jndiName, Factory<Connection> factory, ResultSetMapper cm, final int maxEntries) {
|
||||||
super(conn, jndiName, cm);
|
super(conn, jndiName, factory, cm);
|
||||||
if (maxEntries > 0) { // we want a limited cache
|
if (maxEntries > 0) { // we want a limited cache
|
||||||
final float loadFactor = 0.75f; // default for HashMaps
|
final float loadFactor = 0.75f; // default for HashMaps
|
||||||
// if we set the initialCapacity this way, nothing should ever need re-sized
|
// if we set the initialCapacity this way, nothing should ever need re-sized
|
||||||
@ -43,40 +43,56 @@ public class CachingQueryMapper extends QueryMapper {
|
|||||||
cache = new HashMap<String, PreparedStatement>();
|
cache = new HashMap<String, PreparedStatement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected CachingQueryMapper(Connection conn, String jndiName, Factory<Connection> factory, ResultSetMapper cm) {
|
||||||
|
this(conn, jndiName, factory, cm, 20); // default size of 20
|
||||||
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(Connection conn, ResultSetMapper cm, final int maxEntries) {
|
public CachingQueryMapper(Connection conn, ResultSetMapper cm, final int maxEntries) {
|
||||||
this(conn, null, cm, maxEntries);
|
this(conn, null, null, cm, maxEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(Connection conn, final int maxEntries) {
|
public CachingQueryMapper(Connection conn, final int maxEntries) {
|
||||||
this(conn, null, null, maxEntries);
|
this(conn, null, null, null, maxEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(String jndiName, ResultSetMapper cm, final int maxEntries) {
|
public CachingQueryMapper(String jndiName, ResultSetMapper cm, final int maxEntries) {
|
||||||
this(null, jndiName, cm, maxEntries);
|
this(null, jndiName, null, cm, maxEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(String jndiName, final int maxEntries) {
|
public CachingQueryMapper(String jndiName, final int maxEntries) {
|
||||||
this(null, jndiName, null, maxEntries);
|
this(null, jndiName, null, null, maxEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CachingQueryMapper(Connection conn, String jndiName, ResultSetMapper cm) {
|
public CachingQueryMapper(Factory<Connection> factory, ResultSetMapper cm, final int maxEntries) {
|
||||||
this(conn, jndiName, cm, 20); // default size of 20
|
this(null, null, factory, cm, maxEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachingQueryMapper(Factory<Connection> factory, final int maxEntries) {
|
||||||
|
this(null, null, factory, null, maxEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(Connection conn, ResultSetMapper cm) {
|
public CachingQueryMapper(Connection conn, ResultSetMapper cm) {
|
||||||
this(conn, null, cm);
|
this(conn, null, null, cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(Connection conn) {
|
public CachingQueryMapper(Connection conn) {
|
||||||
this(conn, null, null);
|
this(conn, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(String jndiName, ResultSetMapper cm) {
|
public CachingQueryMapper(String jndiName, ResultSetMapper cm) {
|
||||||
this(null, jndiName, cm);
|
this(null, jndiName, null, cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachingQueryMapper(String jndiName) {
|
public CachingQueryMapper(String jndiName) {
|
||||||
this(null, jndiName, null);
|
this(null, jndiName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachingQueryMapper(Factory<Connection> factory, ResultSetMapper cm) {
|
||||||
|
this(null, null, factory, cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachingQueryMapper(Factory<Connection> factory) {
|
||||||
|
this(null, null, factory, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PreparedStatement getPreparedStatement(String sql) throws SQLException {
|
protected PreparedStatement getPreparedStatement(String sql) throws SQLException {
|
||||||
|
@ -34,26 +34,26 @@ public class ListQueryMapper extends QueryMapper {
|
|||||||
|
|
||||||
public static final String inListReplace = "{inList}";
|
public static final String inListReplace = "{inList}";
|
||||||
|
|
||||||
private ListQueryMapper(Connection conn, String jndiName, QueryMapper delegate, ResultSetMapper cm, InList inList) {
|
private ListQueryMapper(Connection conn, String jndiName, Factory<Connection> factory, QueryMapper delegate, ResultSetMapper cm, InList inList) {
|
||||||
this.inList = inList;
|
this.inList = inList;
|
||||||
this.delegate = delegate == null ? new QueryMapper(conn, jndiName, cm) :
|
this.delegate = delegate == null ? new QueryMapper(conn, jndiName, factory, cm) :
|
||||||
(delegate instanceof ListQueryMapper ? ((ListQueryMapper)delegate).delegate : delegate);
|
(delegate instanceof ListQueryMapper ? ((ListQueryMapper)delegate).delegate : delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(QueryMapper delegate, InList inList) {
|
public ListQueryMapper(QueryMapper delegate, InList inList) {
|
||||||
this(null, null, delegate, null, inList);
|
this(null, null, null, delegate, null, inList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(QueryMapper delegate) {
|
public ListQueryMapper(QueryMapper delegate) {
|
||||||
this(null, null, delegate, null, defaultInList);
|
this(null, null, null, delegate, null, defaultInList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(Connection conn, InList inList) {
|
public ListQueryMapper(Connection conn, InList inList) {
|
||||||
this(conn, null, null, null, inList);
|
this(conn, null, null, null, null, inList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(Connection conn, ResultSetMapper cm, InList inList) {
|
public ListQueryMapper(Connection conn, ResultSetMapper cm, InList inList) {
|
||||||
this(conn, null, null, cm, inList);
|
this(conn, null, null, null, cm, inList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(Connection conn) {
|
public ListQueryMapper(Connection conn) {
|
||||||
@ -65,11 +65,11 @@ public class ListQueryMapper extends QueryMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(String jndiName, InList inList) {
|
public ListQueryMapper(String jndiName, InList inList) {
|
||||||
this(null, jndiName, null, null, inList);
|
this(null, jndiName, null, null, null, inList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(String jndiName, ResultSetMapper cm, InList inList) {
|
public ListQueryMapper(String jndiName, ResultSetMapper cm, InList inList) {
|
||||||
this(null, jndiName, null, cm, inList);
|
this(null, jndiName, null, null, cm, inList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListQueryMapper(String jndiName) {
|
public ListQueryMapper(String jndiName) {
|
||||||
@ -80,6 +80,23 @@ public class ListQueryMapper extends QueryMapper {
|
|||||||
this(jndiName, cm, defaultInList);
|
this(jndiName, cm, defaultInList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListQueryMapper(Factory<Connection> factory, InList inList) {
|
||||||
|
this(null, null, factory, null, null, inList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListQueryMapper(Factory<Connection> factory, ResultSetMapper cm, InList inList) {
|
||||||
|
this(null, null, factory, null, cm, inList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListQueryMapper(Factory<Connection> factory) {
|
||||||
|
this(factory, defaultInList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListQueryMapper(Factory<Connection> factory, ResultSetMapper cm) {
|
||||||
|
this(factory, cm, defaultInList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: get rid of wrap, cause, how do you know to close it or not? :'(
|
||||||
public static ListQueryMapper wrap(final QueryMapper qm){
|
public static ListQueryMapper wrap(final QueryMapper qm){
|
||||||
return qm instanceof ListQueryMapper ? (ListQueryMapper)qm : new ListQueryMapper(qm);
|
return qm instanceof ListQueryMapper ? (ListQueryMapper)qm : new ListQueryMapper(qm);
|
||||||
}
|
}
|
||||||
|
@ -16,25 +16,25 @@ public class NullQueryMapper extends QueryMapper {
|
|||||||
protected final boolean verbose;
|
protected final boolean verbose;
|
||||||
protected final QueryMapper delegate;
|
protected final QueryMapper delegate;
|
||||||
|
|
||||||
private NullQueryMapper(Connection conn, String jndiName, QueryMapper delegate, ResultSetMapper cm, boolean verbose) {
|
private NullQueryMapper(Connection conn, String jndiName, Factory<Connection> factory, QueryMapper delegate, ResultSetMapper cm, boolean verbose) {
|
||||||
this.verbose = verbose;
|
this.verbose = verbose;
|
||||||
this.delegate = delegate == null ? new QueryMapper(conn, jndiName, cm) : delegate;
|
this.delegate = delegate == null ? new QueryMapper(conn, jndiName, factory, cm) : delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(QueryMapper delegate, boolean verbose) {
|
public NullQueryMapper(QueryMapper delegate, boolean verbose) {
|
||||||
this(null, null, delegate, null, verbose);
|
this(null, null, null, delegate, null, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(QueryMapper delegate) {
|
public NullQueryMapper(QueryMapper delegate) {
|
||||||
this(null, null, delegate, null, true);
|
this(null, null, null, delegate, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(Connection conn, boolean verbose) {
|
public NullQueryMapper(Connection conn, boolean verbose) {
|
||||||
this(conn, null, null, null, verbose);
|
this(conn, null, null, null, null, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(Connection conn, ResultSetMapper cm, boolean verbose) {
|
public NullQueryMapper(Connection conn, ResultSetMapper cm, boolean verbose) {
|
||||||
this(conn, null, null, cm, verbose);
|
this(conn, null, null, null, cm, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(Connection conn) {
|
public NullQueryMapper(Connection conn) {
|
||||||
@ -46,11 +46,11 @@ public class NullQueryMapper extends QueryMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(String jndiName, boolean verbose) {
|
public NullQueryMapper(String jndiName, boolean verbose) {
|
||||||
this(null, jndiName, null, null, verbose);
|
this(null, jndiName, null, null, null, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(String jndiName, ResultSetMapper cm, boolean verbose) {
|
public NullQueryMapper(String jndiName, ResultSetMapper cm, boolean verbose) {
|
||||||
this(null, jndiName, null, cm, verbose);
|
this(null, jndiName, null, null, cm, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullQueryMapper(String jndiName) {
|
public NullQueryMapper(String jndiName) {
|
||||||
@ -61,6 +61,23 @@ public class NullQueryMapper extends QueryMapper {
|
|||||||
this(jndiName, cm, true);
|
this(jndiName, cm, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NullQueryMapper(Factory<Connection> factory, boolean verbose) {
|
||||||
|
this(null, null, factory, null, null, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NullQueryMapper(Factory<Connection> factory, ResultSetMapper cm, boolean verbose) {
|
||||||
|
this(null, null, factory, null, cm, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NullQueryMapper(Factory<Connection> factory) {
|
||||||
|
this(factory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NullQueryMapper(Factory<Connection> factory, ResultSetMapper cm) {
|
||||||
|
this(factory, cm, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: remove this refer to ListQueryMapper for why
|
||||||
public static NullQueryMapper wrap(final QueryMapper qm){
|
public static NullQueryMapper wrap(final QueryMapper qm){
|
||||||
return qm instanceof NullQueryMapper ? (NullQueryMapper)qm : new NullQueryMapper(qm);
|
return qm instanceof NullQueryMapper ? (NullQueryMapper)qm : new NullQueryMapper(qm);
|
||||||
}
|
}
|
||||||
|
@ -36,29 +36,40 @@ public class QueryMapper implements JdbcMapper {
|
|||||||
protected final ResultSetMapper cm;
|
protected final ResultSetMapper cm;
|
||||||
protected final Connection conn;
|
protected final Connection conn;
|
||||||
protected final Context context;
|
protected final Context context;
|
||||||
|
protected final boolean closeConn;
|
||||||
|
|
||||||
protected QueryMapper(Connection conn, String jndiName, ResultSetMapper cm) {
|
protected QueryMapper(Connection conn, final String jndiName, final Factory<Connection> factory, final ResultSetMapper cm) {
|
||||||
this.cm = cm == null ? defaultRsm : cm;
|
this.cm = cm == null ? defaultRsm : cm;
|
||||||
|
boolean closeConn = false;
|
||||||
Context context = null;
|
Context context = null;
|
||||||
if (conn == null && jndiName != null)
|
if(conn == null) {
|
||||||
try {
|
if (factory != null) {
|
||||||
context = new InitialContext();
|
try {
|
||||||
DataSource ds = (DataSource) context.lookup(jndiName);
|
conn = factory.create();
|
||||||
conn = ds.getConnection();
|
closeConn = true;
|
||||||
} catch (Throwable e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException("factory failed to create connection", e);
|
||||||
tryClose(conn);
|
}
|
||||||
} finally {
|
} else if (jndiName != null)
|
||||||
tryClose(context);
|
try {
|
||||||
}
|
context = new InitialContext();
|
||||||
|
DataSource ds = (DataSource) context.lookup(jndiName);
|
||||||
|
conn = ds.getConnection();
|
||||||
|
closeConn = true;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
tryClose(context);
|
||||||
|
throw new RuntimeException("JNDI lookup failed to create connection", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (conn == null)
|
||||||
|
throw new NullPointerException("Connection needs to be non-null for QueryMapper...");
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
if (this.conn == null)
|
this.closeConn = closeConn;
|
||||||
throw new NullPointerException("Connection needs to be non-null for QueryMapper...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryMapper(Connection conn, ResultSetMapper cm) {
|
public QueryMapper(Connection conn, ResultSetMapper cm) {
|
||||||
this(conn, null, cm);
|
this(conn, null, null, cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryMapper(Connection conn) {
|
public QueryMapper(Connection conn) {
|
||||||
@ -66,13 +77,21 @@ public class QueryMapper implements JdbcMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public QueryMapper(String jndiName, ResultSetMapper cm) {
|
public QueryMapper(String jndiName, ResultSetMapper cm) {
|
||||||
this(null, jndiName, cm);
|
this(null, jndiName, null, cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryMapper(String jndiName) {
|
public QueryMapper(String jndiName) {
|
||||||
this(jndiName, null);
|
this(jndiName, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QueryMapper(Factory<Connection> factory, ResultSetMapper cm) {
|
||||||
|
this(null, null, factory, cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryMapper(Factory<Connection> factory) {
|
||||||
|
this(factory, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only meant to be called by implementing classes
|
* Only meant to be called by implementing classes
|
||||||
*/
|
*/
|
||||||
@ -80,11 +99,12 @@ public class QueryMapper implements JdbcMapper {
|
|||||||
this.cm = null;
|
this.cm = null;
|
||||||
this.conn = null;
|
this.conn = null;
|
||||||
this.context = null;
|
this.context = null;
|
||||||
|
this.closeConn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (context != null) {
|
if (closeConn) {
|
||||||
tryClose(conn);
|
tryClose(conn);
|
||||||
tryClose(context);
|
tryClose(context);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ public class QueryMapperTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Connection getConnection() throws Throwable {
|
public static Connection getConnection() throws SQLException {
|
||||||
return DriverManager.getConnection("jdbc:derby:memory:derbyDB;create=true");
|
return DriverManager.getConnection("jdbc:derby:memory:derbyDB;create=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.moparisthebest.jdbc;
|
||||||
|
|
||||||
|
import com.moparisthebest.jdbc.codegen.JdbcMapperFactory;
|
||||||
|
import com.moparisthebest.jdbc.dto.Person;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import static com.moparisthebest.jdbc.QueryMapperTest.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 7/1/17.
|
||||||
|
*/
|
||||||
|
public class QueryRunnerTest {
|
||||||
|
public static final QueryRunner<QueryMapper> qr = new QueryRunner<QueryMapper>(new JdbcMapperFactory<QueryMapper>(QueryMapper.class, new Factory<Connection>() {
|
||||||
|
@Override
|
||||||
|
public Connection create() throws SQLException {
|
||||||
|
return QueryMapperTest.getConnection();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
private void testPerson(final Person expected, final String query) throws Throwable {
|
||||||
|
final Person actual = qr.runInTransaction(new QueryRunner.Runner<QueryMapper, Person>() {
|
||||||
|
@Override
|
||||||
|
public Person run(final QueryMapper qm) throws SQLException {
|
||||||
|
return qm.toObject(query, expected.getClass(), expected.getPersonNo());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
System.out.println("expected: " + expected);
|
||||||
|
System.out.println("actual: " + actual);
|
||||||
|
*/
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegularPerson() throws Throwable {
|
||||||
|
testPerson(fieldPerson1, personRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegularAndUnderscore() throws Throwable {
|
||||||
|
testPerson(fieldBoss1, bossRegularAndUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegularAndUnderscoreReverse() throws Throwable {
|
||||||
|
testPerson(fieldBoss1, bossRegularAndUnderscoreReverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegular() throws Throwable {
|
||||||
|
testPerson(fieldBoss2, bossRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldUnderscore() throws Throwable {
|
||||||
|
testPerson(fieldBoss3, bossUnderscore);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user