diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingResultSetMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingResultSetMapper.java index 98ce9b5..a48a900 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingResultSetMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingResultSetMapper.java @@ -132,7 +132,7 @@ public class CachingResultSetMapper extends ResultSetMapper { } @Override - protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - return new CachingRowToObjectMapper(cache, resultSet, returnTypeClass, cal, mapValType); + protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + return new CachingRowToObjectMapper(cache, resultSet, returnTypeClass, cal, mapValType, mapKeyType); } } diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingRowToObjectMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingRowToObjectMapper.java index fb3b61d..579036c 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingRowToObjectMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CachingRowToObjectMapper.java @@ -11,18 +11,18 @@ import java.util.Map; /** * Maps same as RowToObjectMapper except caches constructor and field mappings */ -public class CachingRowToObjectMapper extends RowToObjectMapper { +public class CachingRowToObjectMapper extends RowToObjectMapper { protected final Map> cache; protected final ResultSetKey keys; - public CachingRowToObjectMapper(final Map> cache, ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - super(resultSet, returnTypeClass, cal, mapValType); + public CachingRowToObjectMapper(final Map> cache, ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + super(resultSet, returnTypeClass, cal, mapValType, mapKeyType); @SuppressWarnings("unchecked") final Map> genericCache = (Map>) (Object) cache; // ridiculous ain't it? this.cache = genericCache; try { - keys = new ResultSetKey(super.getKeysFromResultSet(), _returnTypeClass); + keys = new ResultSetKey(super.getKeysFromResultSet(), _returnTypeClass, _mapKeyType); //System.out.printf("keys: %s\n", keys); } catch (SQLException e) { throw new MapperException("CachingRowToObjectMapper: SQLException: " + e.getMessage(), e); @@ -55,11 +55,12 @@ public class CachingRowToObjectMapper extends RowToObjectMapper { public static class ResultSetKey { protected final String[] keys; - protected final Class returnTypeClass; + protected final Class returnTypeClass, mapKeyType; - public ResultSetKey(final String[] keys, final Class returnTypeClass) { + public ResultSetKey(final String[] keys, final Class returnTypeClass, final Class mapKeyType) { this.keys = keys; this.returnTypeClass = returnTypeClass; + this.mapKeyType = mapKeyType; } @Override @@ -69,13 +70,18 @@ public class CachingRowToObjectMapper extends RowToObjectMapper { final ResultSetKey that = (ResultSetKey) o; - return Arrays.equals(keys, that.keys) && (returnTypeClass != null ? returnTypeClass.equals(that.returnTypeClass) : that.returnTypeClass == null); + // Probably incorrect - comparing Object[] arrays with Arrays.equals + if (!Arrays.equals(keys, that.keys)) return false; + if (returnTypeClass != null ? !returnTypeClass.equals(that.returnTypeClass) : that.returnTypeClass != null) + return false; + return mapKeyType != null ? mapKeyType.equals(that.mapKeyType) : that.mapKeyType == null; } @Override public int hashCode() { int result = Arrays.hashCode(keys); result = 31 * result + (returnTypeClass != null ? returnTypeClass.hashCode() : 0); + result = 31 * result + (mapKeyType != null ? mapKeyType.hashCode() : 0); return result; } @@ -84,6 +90,7 @@ public class CachingRowToObjectMapper extends RowToObjectMapper { return "ResultSetKey{" + "keys=" + Arrays.toString(keys) + ", returnTypeClass=" + returnTypeClass + + ", mapKeyType=" + mapKeyType + '}'; } } diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapResultSetMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapResultSetMapper.java index 8f1cc25..e2b57be 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapResultSetMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapResultSetMapper.java @@ -15,7 +15,7 @@ public class CaseInsensitiveMapResultSetMapper extends ResultSetMapper { } @Override - protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - return new CaseInsensitiveMapRowToObjectMapper(resultSet, returnTypeClass, cal, mapValType); + protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + return new CaseInsensitiveMapRowToObjectMapper(resultSet, returnTypeClass, cal, mapValType, mapKeyType); } } diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapRowToObjectMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapRowToObjectMapper.java index 3ac31b9..bbe8242 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapRowToObjectMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CaseInsensitiveMapRowToObjectMapper.java @@ -8,7 +8,7 @@ import java.util.Map; /** * Created by mopar on 5/15/14. */ -public class CaseInsensitiveMapRowToObjectMapper extends RowToObjectMapper { +public class CaseInsensitiveMapRowToObjectMapper extends RowToObjectMapper { public CaseInsensitiveMapRowToObjectMapper(ResultSet resultSet, Class returnTypeClass) { super(resultSet, returnTypeClass); } @@ -25,6 +25,10 @@ public class CaseInsensitiveMapRowToObjectMapper extends RowToObjectMapper super(resultSet, returnTypeClass, cal, mapValType); } + public CaseInsensitiveMapRowToObjectMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + super(resultSet, returnTypeClass, cal, mapValType, mapKeyType); + } + @Override protected Map getMapImplementation() throws IllegalAccessException, InstantiationException { if(HashMap.class.equals(_returnTypeClass)) diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningResultSetMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningResultSetMapper.java index 14f77eb..5139003 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningResultSetMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningResultSetMapper.java @@ -19,7 +19,7 @@ public class CleaningResultSetMapper extends ResultSetMapper { @Override @SuppressWarnings({"unchecked"}) - protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - return new CleaningRowToObjectMapper((Cleaner)cleaner, resultSet, returnTypeClass, cal, mapValType); + protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + return new CleaningRowToObjectMapper((Cleaner)cleaner, resultSet, returnTypeClass, cal, mapValType, mapKeyType); } } diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningRowToObjectMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningRowToObjectMapper.java index 91d3388..bfe7ea9 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningRowToObjectMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CleaningRowToObjectMapper.java @@ -1,21 +1,22 @@ package com.moparisthebest.jdbc; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Calendar; -public class CleaningRowToObjectMapper extends RowToObjectMapper { +public class CleaningRowToObjectMapper extends RowToObjectMapper { private final Cleaner cleaner; - public CleaningRowToObjectMapper(Cleaner cleaner, ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - super(resultSet, returnTypeClass, cal, mapValType); + public CleaningRowToObjectMapper(Cleaner cleaner, ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + super(resultSet, returnTypeClass, cal, mapValType, mapKeyType); if (cleaner == null) throw new NullPointerException("cleaner cannot be null!"); this.cleaner = cleaner; } @Override - public T mapRowToReturnType() { + public T mapRowToReturnType() throws SQLException { return cleaner.clean(super.mapRowToReturnType()); } } diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingResultSetMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingResultSetMapper.java index 30a2df2..3ef4c0b 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingResultSetMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingResultSetMapper.java @@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; public class CompilingResultSetMapper extends ResultSetMapper { protected final Compiler compiler = new Compiler(); - protected final Map> cache; + protected final Map> cache; /** * CompilingResultSetMapper with optional maxEntries, expiring old ones in LRU fashion @@ -40,14 +40,14 @@ public class CompilingResultSetMapper extends ResultSetMapper { final float loadFactor = 0.75f; // default for HashMaps // if we set the initialCapacity this way, nothing should ever need re-sized final int initialCapacity = ((int) Math.ceil(maxEntries / loadFactor)) + 1; - cache = new LinkedHashMap>(initialCapacity, loadFactor, true) { + cache = new LinkedHashMap>(initialCapacity, loadFactor, true) { @Override - protected boolean removeEldestEntry(final Map.Entry> eldest) { + protected boolean removeEldestEntry(final Map.Entry> eldest) { return size() > maxEntries; } }; } else - cache = new HashMap>(); + cache = new HashMap>(); } /** @@ -83,7 +83,7 @@ public class CompilingResultSetMapper extends ResultSetMapper { * @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included * @param cache any Map implementation for cache you wish, does not need to handle null keys or values */ - public CompilingResultSetMapper(final Calendar cal, final int arrayMaxLength, final Map> cache) { + public CompilingResultSetMapper(final Calendar cal, final int arrayMaxLength, final Map> cache) { super(cal, arrayMaxLength); if (cache == null) throw new IllegalArgumentException("cache cannot be null"); @@ -96,7 +96,7 @@ public class CompilingResultSetMapper extends ResultSetMapper { * @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included * @param cache any Map implementation for cache you wish, does not need to handle null keys or values */ - public CompilingResultSetMapper(final int arrayMaxLength, final Map> cache) { + public CompilingResultSetMapper(final int arrayMaxLength, final Map> cache) { this(null, arrayMaxLength, cache); } @@ -105,7 +105,7 @@ public class CompilingResultSetMapper extends ResultSetMapper { * * @param cache any Map implementation for cache you wish, does not need to handle null keys or values */ - public CompilingResultSetMapper(final Map> cache) { + public CompilingResultSetMapper(final Map> cache) { this(-1, cache); } @@ -118,9 +118,9 @@ public class CompilingResultSetMapper extends ResultSetMapper { */ public CompilingResultSetMapper(final Calendar cal, final int arrayMaxLength, final boolean threadSafe) { this(cal, arrayMaxLength, threadSafe ? - new ConcurrentHashMap>() + new ConcurrentHashMap>() : - new HashMap>() + new HashMap>() ); } @@ -144,7 +144,7 @@ public class CompilingResultSetMapper extends ResultSetMapper { } @Override - protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - return new CompilingRowToObjectMapper(compiler, cache, resultSet, returnTypeClass, cal, mapValType); + protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + return new CompilingRowToObjectMapper(compiler, cache, resultSet, returnTypeClass, cal, mapValType, mapKeyType); } } diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java index 2d360dd..879a534 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java @@ -26,20 +26,23 @@ import java.util.Map; * 1. Normally a subclass of RowToObjectMapper can overload the getMapImplementation() method to change some behavior, * @see CaseInsensitiveMapRowToObjectMapper , but that method is never called with this implementation. */ -public class CompilingRowToObjectMapper extends RowToObjectMapper { +public class CompilingRowToObjectMapper extends RowToObjectMapper { + + public static final String firstColumnError = "Cannot call getFirstColumn when mapKeyType is null!"; + protected final Compiler compiler; - protected final ResultSetToObject resultSetToObject; + protected final ResultSetToObject resultSetToObject; protected String[] keys = null; // for caching if we must generate class - public CompilingRowToObjectMapper(final Compiler compiler, final Map> cache, ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - super(resultSet, returnTypeClass, cal, mapValType); + public CompilingRowToObjectMapper(final Compiler compiler, final Map> cache, ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + super(resultSet, returnTypeClass, cal, mapValType, mapKeyType); this.compiler = compiler; try { - final CachingRowToObjectMapper.ResultSetKey keys = new CachingRowToObjectMapper.ResultSetKey(super.getKeysFromResultSet(), _returnTypeClass); + final CachingRowToObjectMapper.ResultSetKey keys = new CachingRowToObjectMapper.ResultSetKey(super.getKeysFromResultSet(), _returnTypeClass, _mapKeyType); //System.out.printf("keys: %s\n", keys); @SuppressWarnings("unchecked") - final ResultSetToObject resultSetToObject = (ResultSetToObject) cache.get(keys); + final ResultSetToObject resultSetToObject = (ResultSetToObject) cache.get(keys); if (resultSetToObject == null) { //System.out.printf("cache miss, keys: %s\n", keys); // generate and put into cache @@ -60,15 +63,15 @@ public class CompilingRowToObjectMapper extends RowToObjectMapper { } @Override - public T mapRowToReturnType() { - try { - return resultSetToObject.toObject(_resultSet, _cal); - } catch (SQLException e) { - throw new MapperException(e.getMessage(), e); - } + public T mapRowToReturnType() throws SQLException { + return resultSetToObject.toObject(_resultSet, _cal); } - // todo: generate/cache these to make it faster for Map and MapCollection? maybe just getKey and getVal methods instead + @Override + public K getMapKey() throws SQLException { + return resultSetToObject.getFirstColumn(_resultSet, _cal); + } +// todo: generate/cache these to make it faster for Map and MapCollection? maybe just getKey and getVal methods instead /* @Override public E extractColumnValue(final int index, final Class classType) throws SQLException { @@ -88,11 +91,14 @@ public class CompilingRowToObjectMapper extends RowToObjectMapper { throw new MapperException("not supported here"); } - public interface ResultSetToObject { + public interface ResultSetToObject { + K getFirstColumn(final ResultSet rs, final Calendar cal) throws SQLException; T toObject(final ResultSet rs, final Calendar cal) throws SQLException; } protected String typeFromName(final Class type) { + if(type == null) + return "Object"; if(_columnCount == 1 && type.isPrimitive()) { // need the object equivalent here, what is the best way? this works, isn't pretty... if(type.equals(Character.TYPE)) @@ -141,27 +147,44 @@ public class CompilingRowToObjectMapper extends RowToObjectMapper { } // code generation down here - protected ResultSetToObject genClass() { + protected ResultSetToObject genClass() { final String className = "CompilingMapper"; final String tType = typeFromName(_returnTypeClass); + final String kType = typeFromName(_mapKeyType); final String header = "import static com.moparisthebest.jdbc.util.ResultSetUtil.*;\n\n" + "public final class " + className + - " implements com.moparisthebest.jdbc.CompilingRowToObjectMapper.ResultSetToObject<" + tType + "> {\n" + + " implements com.moparisthebest.jdbc.CompilingRowToObjectMapper.ResultSetToObject<"+ kType +"," + tType + "> {\n" + " public " + tType + " toObject(final java.sql.ResultSet rs, final java.util.Calendar cal) throws java.sql.SQLException {\n"; - final String footer = " }\n" + + final String footer = ";\n }\n" + "}\n"; final StringBuilder java = new StringBuilder(header); //java.append("return null;\n"); gen(java, tType); + + java.append(" }\n\n public ").append(kType).append(" getFirstColumn(final java.sql.ResultSet rs, final java.util.Calendar cal) throws java.sql.SQLException {\n "); + if(_mapKeyType != null){ + java.append("return "); + extractColumnValueString(java, 1, _tmf.getTypeId(_mapKeyType)); + } else { + java.append("throw new com.moparisthebest.jdbc.MapperException(com.moparisthebest.jdbc.CompilingRowToObjectMapper.firstColumnError)"); + } + java.append(footer); - //System.out.println(java); + System.out.println(java); return compiler.compile(className, java); } protected void gen(final StringBuilder java, final String tType) { + if(mapOnlySecondColumn){ + java.append("return "); + extractColumnValueString(java, 2, _tmf.getTypeId(_returnTypeClass)); + java.append(";\n"); + return; + } + lazyLoadConstructor(); if (resultSetConstructor) { diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java index 45c3ec1..7bae004 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java @@ -120,7 +120,7 @@ public class ResultSetMapper { T ret = null; try { if (rs.next()) - ret = getRowMapper(rs, componentType, cal, mapValType).mapRowToReturnType(); + ret = getRowMapper(rs, componentType, cal, mapValType, null).mapRowToReturnType(); } catch (SQLException e) { // ignore } @@ -151,7 +151,7 @@ public class ResultSetMapper { // a value of less than 1 indicates that all rows from the ResultSet should be included. final boolean unlimitedRows = arrayMaxLength < 1; - final RowToObjectMapper rowMapper = getRowMapper(rs, componentType, cal, mapValType); + final RowToObjectMapper rowMapper = getRowMapper(rs, componentType, cal, mapValType, null); for (; (unlimitedRows || numRows != arrayMaxLength) && rs.next(); ++numRows) { E object = rowMapper.mapRowToReturnType(); @@ -230,12 +230,11 @@ public class ResultSetMapper { // a value of less than 1 indicates that all rows from the ResultSet should be included. final boolean unlimitedRows = arrayMaxLength < 1; - final RowToObjectMapper rowMapper = getRowMapper(rs, componentType, cal, mapValType); + final RowToObjectMapper rowMapper = getRowMapper(rs, componentType, cal, mapValType, mapKeyType); - boolean onlyTwoColumns = rowMapper.getColumnCount() == 2; for (; (unlimitedRows || numRows != arrayMaxLength) && rs.next(); ++numRows) { - K key = rowMapper.extractColumnValue(1, mapKeyType); - E value = onlyTwoColumns ? rowMapper.extractColumnValue(2, componentType) : rowMapper.mapRowToReturnType(); + K key = rowMapper.getMapKey(); + E value = rowMapper.mapRowToReturnType(); map = softMap.get(); if (map == null) @@ -312,12 +311,11 @@ public class ResultSetMapper { // a value of less than 1 indicates that all rows from the ResultSet should be included. final boolean unlimitedRows = arrayMaxLength < 1; - final RowToObjectMapper rowMapper = getRowMapper(rs, componentType, cal, mapValType); + final RowToObjectMapper rowMapper = getRowMapper(rs, componentType, cal, mapValType, mapKeyType); - boolean onlyTwoColumns = rowMapper.getColumnCount() == 2; for (; (unlimitedRows || numRows != arrayMaxLength) && rs.next(); ++numRows) { - K key = rowMapper.extractColumnValue(1, mapKeyType); - C value = onlyTwoColumns ? rowMapper.extractColumnValue(2, componentType) : rowMapper.mapRowToReturnType(); + K key = rowMapper.getMapKey(); + C value = rowMapper.mapRowToReturnType(); map = softMap.get(); if (map == null) @@ -406,8 +404,8 @@ public class ResultSetMapper { } // fairly un-interesting methods below here - protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - return new RowToObjectMapper(resultSet, returnTypeClass, cal, mapValType); + protected RowToObjectMapper getRowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + return new RowToObjectMapper(resultSet, returnTypeClass, cal, mapValType, mapKeyType); } protected void warnOnMaxLength(final int numRows, final int arrayMaxLength, final ResultSet rs) { diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowMapper.java index f9dc5e3..de4dd89 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowMapper.java @@ -37,7 +37,7 @@ import java.util.regex.Pattern; * RowMapperFactory. * */ -public abstract class RowMapper { +public abstract class RowMapper { private static final String SETTER_NAME_REGEX = "^(set)([A-Z_]\\w*+)"; protected static final TypeMappingsFactory _tmf = TypeMappingsFactory.getInstance(); @@ -50,34 +50,51 @@ public abstract class RowMapper { protected final Calendar _cal; /** Class to map ResultSet Rows to. */ - protected final Class _returnTypeClass; + protected final Class _returnTypeClass; + + protected final Class _mapKeyType; protected final int _columnCount; + protected final boolean mapOnlySecondColumn; + /** * Create a new RowMapper for the specified ResultSet and return type Class. * @param resultSet ResultSet to map * @param returnTypeClass Class to map ResultSet rows to. * @param cal Calendar instance for date/time values. */ - protected RowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal) { + protected RowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapKeyType) { _resultSet = resultSet; _returnTypeClass = returnTypeClass; _cal = cal; + _mapKeyType = mapKeyType; try { _columnCount = resultSet.getMetaData().getColumnCount(); } catch (SQLException e) { throw new MapperException("RowToObjectMapper: SQLException: " + e.getMessage(), e); } + + mapOnlySecondColumn = _mapKeyType != null && _columnCount == 2; + } + + protected RowMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal) { + this(resultSet, returnTypeClass, cal, null); } /** * Map a ResultSet row to the return type class - * @return An instance of class. + * @return An instance of class, if _mapKeyType is not null and _columnCount is 2, return only index 2 */ - public abstract Object mapRowToReturnType(); + public abstract T mapRowToReturnType() throws SQLException; + /** + * key for map + * @return index number 1, with type of _mapKeyType + * @throws MapperException if _mapKeyType is null + */ + public abstract K getMapKey() throws SQLException; /** * Build a String array of column names from the ResultSet. diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java index 79325d0..b3bd4a2 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java @@ -47,7 +47,7 @@ import static com.moparisthebest.jdbc.UpdateableDTO.NO; * * @author Travis Burtrum (modifications from beehive) */ -public class RowToObjectMapper extends RowMapper { +public class RowToObjectMapper extends RowMapper { 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? @@ -77,6 +77,11 @@ public class RowToObjectMapper extends RowMapper { this(resultSet, returnTypeClass, cal, null); } + + public RowToObjectMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { + this(resultSet, returnTypeClass, cal, mapValType, null); + } + /** * Create a new RowToObjectMapper. * @@ -84,8 +89,8 @@ public class RowToObjectMapper extends RowMapper { * @param returnTypeClass Class to map to. * @param cal Calendar instance for date/time mappings. */ - public RowToObjectMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType) { - super(resultSet, returnTypeClass, cal); + public RowToObjectMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal, Class mapValType, Class mapKeyType) { + super(resultSet, returnTypeClass, cal, mapKeyType); returnMap = Map.class.isAssignableFrom(returnTypeClass); if(returnMap){ _returnTypeClass = ResultSetMapper.getConcreteClass(returnTypeClass, HashMap.class); @@ -136,13 +141,21 @@ public class RowToObjectMapper extends RowMapper { return (Map)_returnTypeClass.newInstance(); } + @Override + public K getMapKey() throws SQLException { + return this.extractColumnValue(1, _mapKeyType); + } + /** * Do the mapping. * * @return An object instance. */ @SuppressWarnings({"unchecked"}) - public T mapRowToReturnType() { + public T mapRowToReturnType() throws SQLException { + + if(mapOnlySecondColumn) + return this.extractColumnValue(2, _returnTypeClass); lazyLoadConstructor(); @@ -300,15 +313,6 @@ public class RowToObjectMapper extends RowMapper { return classType.cast(extractColumnValue(index, _tmf.getTypeId(classType))); } - /** - * Provided so we know whether to map all values to a type, or just the second one - * - * @return - */ - public int getColumnCount() { - return this._columnCount; - } - /** * Build the structures necessary to do the mapping * diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/StaticCompilingResultSetMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/StaticCompilingResultSetMapper.java index 1ec61b7..c2a2f31 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/StaticCompilingResultSetMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/StaticCompilingResultSetMapper.java @@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentHashMap; */ public class StaticCompilingResultSetMapper extends CompilingResultSetMapper { - private static final Map> cache = new ConcurrentHashMap>(); + private static final Map> cache = new ConcurrentHashMap>(); public static final StaticCompilingResultSetMapper instance = new StaticCompilingResultSetMapper();