Some re-factoring for lazy loading

This commit is contained in:
Travis Burtrum 2017-05-17 13:07:08 -04:00
parent 9310c759e6
commit f97ad82389
3 changed files with 27 additions and 19 deletions

View File

@ -48,6 +48,7 @@ public class CompilingRowToObjectMapper<T> extends RowToObjectMapper<T> {
this.keys = null; this.keys = null;
this._fields = null; this._fields = null;
this._fieldTypes = null; this._fieldTypes = null;
this.constructor = null;
} else { } else {
//System.out.printf("cache hit, keys: %s\n", keys); //System.out.printf("cache hit, keys: %s\n", keys);
// load from cache // load from cache
@ -144,6 +145,8 @@ public class CompilingRowToObjectMapper<T> extends RowToObjectMapper<T> {
protected void gen(final StringBuilder java, final String tType) { protected void gen(final StringBuilder java, final String tType) {
lazyLoadConstructor();
if (resultSetConstructor) { if (resultSetConstructor) {
java.append("return new ").append(tType).append("(rs);\n"); java.append("return new ").append(tType).append("(rs);\n");
return; return;

View File

@ -52,6 +52,8 @@ public abstract class RowMapper {
/** Class to map ResultSet Rows to. */ /** Class to map ResultSet Rows to. */
protected final Class<?> _returnTypeClass; protected final Class<?> _returnTypeClass;
protected final int _columnCount;
/** /**
* Create a new RowMapper for the specified ResultSet and return type Class. * Create a new RowMapper for the specified ResultSet and return type Class.
* @param resultSet ResultSet to map * @param resultSet ResultSet to map
@ -62,6 +64,12 @@ public abstract class RowMapper {
_resultSet = resultSet; _resultSet = resultSet;
_returnTypeClass = returnTypeClass; _returnTypeClass = returnTypeClass;
_cal = cal; _cal = cal;
try {
_columnCount = resultSet.getMetaData().getColumnCount();
} catch (SQLException e) {
throw new MapperException("RowToObjectMapper: SQLException: " + e.getMessage(), e);
}
} }
/** /**
@ -80,10 +88,9 @@ public abstract class RowMapper {
String[] keys; String[] keys;
final ResultSetMetaData md = _resultSet.getMetaData(); final ResultSetMetaData md = _resultSet.getMetaData();
final int columnCount = md.getColumnCount();
keys = new String[columnCount + 1]; keys = new String[_columnCount + 1];
for (int i = 1; i <= columnCount; i++) { for (int i = 1; i <= _columnCount; i++) {
keys[i] = md.getColumnName(i).toUpperCase(); keys[i] = md.getColumnName(i).toUpperCase();
} }
return keys; return keys;

View File

@ -52,16 +52,15 @@ public class RowToObjectMapper<T> extends RowMapper {
public static final int TYPE_BOOLEAN = _tmf.getTypeId(Boolean.TYPE);//TypeMappingsFactory.TYPE_BOOLEAN; // not public? public static final int TYPE_BOOLEAN = _tmf.getTypeId(Boolean.TYPE);//TypeMappingsFactory.TYPE_BOOLEAN; // not public?
public static final int TYPE_BOOLEAN_OBJ = _tmf.getTypeId(Boolean.class);//TypeMappingsFactory.TYPE_BOOLEAN_OBJ; // not public? public static final int TYPE_BOOLEAN_OBJ = _tmf.getTypeId(Boolean.class);//TypeMappingsFactory.TYPE_BOOLEAN_OBJ; // not public?
protected final int _columnCount; protected boolean resultSetConstructor, constructorLoaded = false;
protected final boolean resultSetConstructor; protected Constructor<? extends T> constructor;
protected final Constructor<T> constructor;
protected final Class<? extends T> _returnTypeClass; // over-ride non-generic version of this in super class protected final Class<? extends T> _returnTypeClass; // over-ride non-generic version of this in super class
// only non-null when _returnTypeClass is an array, or a map // only non-null when _returnTypeClass is an array, or a map
protected final Class<?> componentType; protected final Class<?> componentType;
protected final boolean returnMap; protected final boolean returnMap;
protected AccessibleObject[] _fields; protected AccessibleObject[] _fields = null;
protected int[] _fieldTypes; protected int[] _fieldTypes;
protected final Object[] _args = new Object[1]; protected final Object[] _args = new Object[1];
@ -96,38 +95,35 @@ public class RowToObjectMapper<T> extends RowMapper {
// detect if we want an array back // detect if we want an array back
componentType = returnTypeClass.getComponentType(); componentType = returnTypeClass.getComponentType();
} }
_fields = null;
try {
_columnCount = resultSet.getMetaData().getColumnCount();
} catch (SQLException e) {
throw new MapperException("RowToObjectMapper: SQLException: " + e.getMessage(), e);
} }
protected void lazyLoadConstructor() {
if(constructorLoaded)
return;
// detect if returnTypeClass has a constructor that takes a ResultSet, if so, our job couldn't be easier... // detect if returnTypeClass has a constructor that takes a ResultSet, if so, our job couldn't be easier...
boolean resultSetConstructor = false; boolean resultSetConstructor = false;
Constructor<T> constructor = null; Constructor<? extends T> constructor = null;
try { try {
constructor = returnTypeClass.getConstructor(ResultSet.class); constructor = _returnTypeClass.getConstructor(ResultSet.class);
if (!constructor.isAccessible()) if (!constructor.isAccessible())
constructor.setAccessible(true); constructor.setAccessible(true);
resultSetConstructor = true; resultSetConstructor = true;
} catch (Throwable e) { } catch (Throwable e) {
// if no resultSetConstructor find the constructor // if no resultSetConstructor find the constructor
try { try {
constructor = returnTypeClass.getDeclaredConstructor(); constructor = _returnTypeClass.getDeclaredConstructor();
if (!constructor.isAccessible()) if (!constructor.isAccessible())
constructor.setAccessible(true); constructor.setAccessible(true);
} catch (Throwable e1) { } catch (Throwable e1) {
// if column count is 2 or less, it might map directly to a type like a Long or something, or be a map which does // if column count is 2 or less, it might map directly to a type like a Long or something, or be a map which does
// or if componentType is non-null, then we want an array like Long[] or String[] // or if componentType is non-null, then we want an array like Long[] or String[]
if(_columnCount > 2 && componentType == null) if(_columnCount > 2 && componentType == null)
throw new MapperException("Exception when trying to get constructor for : "+returnTypeClass.getName() + " Must have default no-arg constructor or one that takes a single ResultSet.", e1); throw new MapperException("Exception when trying to get constructor for : "+_returnTypeClass.getName() + " Must have default no-arg constructor or one that takes a single ResultSet.", e1);
} }
} }
this.resultSetConstructor = resultSetConstructor; this.resultSetConstructor = resultSetConstructor;
this.constructor = constructor; this.constructor = constructor;
this.constructorLoaded = true;
} }
/** /**
@ -148,6 +144,8 @@ public class RowToObjectMapper<T> extends RowMapper {
@SuppressWarnings({"unchecked"}) @SuppressWarnings({"unchecked"})
public T mapRowToReturnType() { public T mapRowToReturnType() {
lazyLoadConstructor();
if (resultSetConstructor) if (resultSetConstructor)
try { try {
return constructor.newInstance(_resultSet); return constructor.newInstance(_resultSet);