Major refactor, more tests
parent
e7639d740c
commit
efd1d44808
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*
|
||||
* $Header:$
|
||||
*/
|
||||
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Abstract base class for all row mappers.
|
||||
*
|
||||
* RowMappers are used to map the contents of a row in a ResultSet to the return type of an annotated method.
|
||||
* Supported RowMapper types include: HashMap, Map, Object, XmlObject. When a ResultSetMapper is ready to
|
||||
* map a ResultSet row to an object, it requests a RowMapper for the return type of the method from the
|
||||
* RowMapperFactory.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractRowMapper<K, T> implements RowMapper<K,T> {
|
||||
|
||||
/** ResultSet to map. */
|
||||
protected final ResultSet _resultSet;
|
||||
|
||||
/** Calendar instance for date/time mappings. */
|
||||
protected final Calendar _cal;
|
||||
|
||||
/** Class to map ResultSet Rows to. */
|
||||
protected final Class<T> _returnTypeClass;
|
||||
|
||||
protected final Class<K> _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 AbstractRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<K> 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 AbstractRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal) {
|
||||
this(resultSet, returnTypeClass, cal, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a String array of column names from the ResultSet.
|
||||
* @return A String array containing the column names contained within the ResultSet.
|
||||
* @throws java.sql.SQLException on error
|
||||
*/
|
||||
protected String[] getKeysFromResultSet() throws SQLException {
|
||||
|
||||
String[] keys;
|
||||
final ResultSetMetaData md = _resultSet.getMetaData();
|
||||
|
||||
keys = new String[_columnCount + 1];
|
||||
for (int i = 1; i <= _columnCount; i++) {
|
||||
keys[i] = md.getColumnName(i).toUpperCase();
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/15/14.
|
||||
*/
|
||||
public class CaseInsensitiveMapRowToObjectMapper<K, T> extends RowToObjectMapper<K, T> {
|
||||
public CaseInsensitiveMapRowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass) {
|
||||
super(resultSet, returnTypeClass);
|
||||
}
|
||||
|
||||
public CaseInsensitiveMapRowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Class<?> mapValType) {
|
||||
super(resultSet, returnTypeClass, mapValType);
|
||||
}
|
||||
|
||||
public CaseInsensitiveMapRowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal) {
|
||||
super(resultSet, returnTypeClass, cal);
|
||||
}
|
||||
|
||||
public CaseInsensitiveMapRowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType) {
|
||||
super(resultSet, returnTypeClass, cal, mapValType);
|
||||
}
|
||||
|
||||
public CaseInsensitiveMapRowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
super(resultSet, returnTypeClass, cal, mapValType, mapKeyType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> getMapImplementation() throws IllegalAccessException, InstantiationException {
|
||||
if(HashMap.class.equals(_returnTypeClass))
|
||||
return new HashMap<String, Object>(){
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return super.get(key instanceof String ? ((String)key).toLowerCase() : key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return super.containsKey(key instanceof String ? ((String)key).toLowerCase() : key);
|
||||
}
|
||||
};
|
||||
return super.getMapImplementation();
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public class CleaningCachingResultSetMapper<E> extends CachingResultSetMapper {
|
||||
|
||||
private final Cleaner<E> cleaner;
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final int maxEntries) {
|
||||
super(cal, arrayMaxLength, maxEntries);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength) {
|
||||
super(cal, arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength) {
|
||||
super(arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner) {
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
super(cal, arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
super(arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
super(cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(cal, arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final boolean threadSafe) {
|
||||
super(threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, T> RowMapper<K, T> getRowMapper(final ResultSet resultSet, final Class<T> returnTypeClass, final Calendar cal, final Class<?> mapValType, final Class<K> mapKeyType) {
|
||||
return new CleaningRowToObjectMapper((Cleaner<T>)cleaner, super.getRowMapper(resultSet, returnTypeClass, cal, mapValType, mapKeyType));
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public class CleaningCompilingResultSetMapper<E> extends CompilingResultSetMapper {
|
||||
|
||||
private final Cleaner<E> cleaner;
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final int maxEntries) {
|
||||
super(cal, arrayMaxLength, maxEntries);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength) {
|
||||
super(cal, arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength) {
|
||||
super(arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner) {
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?, ?>> cache) {
|
||||
super(cal, arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?, ?>> cache) {
|
||||
super(arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?, ?>> cache) {
|
||||
super(cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(cal, arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final boolean threadSafe) {
|
||||
super(threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, T> RowMapper<K, T> getRowMapper(final ResultSet resultSet, final Class<T> returnTypeClass, final Calendar cal, final Class<?> mapValType, final Class<K> mapKeyType) {
|
||||
return new CleaningRowToObjectMapper((Cleaner<T>)cleaner, super.getRowMapper(resultSet, returnTypeClass, cal, mapValType, mapKeyType));
|
||||
}
|
||||
}
|
@ -1,264 +1,21 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*
|
||||
* $Header:$
|
||||
*/
|
||||
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Abstract base class for all row mappers.
|
||||
*
|
||||
* RowMappers are used to map the contents of a row in a ResultSet to the return type of an annotated method.
|
||||
* Supported RowMapper types include: HashMap, Map, Object, XmlObject. When a ResultSetMapper is ready to
|
||||
* map a ResultSet row to an object, it requests a RowMapper for the return type of the method from the
|
||||
* RowMapperFactory.
|
||||
*
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public abstract class RowMapper<K, T> {
|
||||
|
||||
private static final String SETTER_NAME_REGEX = "^(set)([A-Z_]\\w*+)";
|
||||
protected static final TypeMappingsFactory _tmf = TypeMappingsFactory.getInstance();
|
||||
protected static final Pattern _setterRegex = Pattern.compile(SETTER_NAME_REGEX);
|
||||
|
||||
/** ResultSet to map. */
|
||||
protected final ResultSet _resultSet;
|
||||
|
||||
/** Calendar instance for date/time mappings. */
|
||||
protected final Calendar _cal;
|
||||
|
||||
/** Class to map ResultSet Rows to. */
|
||||
protected final Class<T> _returnTypeClass;
|
||||
|
||||
protected final Class<K> _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<T> returnTypeClass, Calendar cal, Class<K> 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<T> returnTypeClass, Calendar cal) {
|
||||
this(resultSet, returnTypeClass, cal, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a ResultSet row to the return type class
|
||||
* @return An instance of class, if _mapKeyType is not null and _columnCount is 2, return only index 2
|
||||
*/
|
||||
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.
|
||||
* @return A String array containing the column names contained within the ResultSet.
|
||||
* @throws java.sql.SQLException on error
|
||||
*/
|
||||
protected String[] getKeysFromResultSet() throws SQLException {
|
||||
|
||||
String[] keys;
|
||||
final ResultSetMetaData md = _resultSet.getMetaData();
|
||||
|
||||
keys = new String[_columnCount + 1];
|
||||
for (int i = 1; i <= _columnCount; i++) {
|
||||
keys[i] = md.getColumnName(i).toUpperCase();
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method is a java bean setter method.
|
||||
* @param method Method to check
|
||||
* @return True if the method is a setter method.
|
||||
*/
|
||||
protected boolean isSetterMethod(Method method) {
|
||||
Matcher matcher = _setterRegex.matcher(method.getName());
|
||||
if (matcher.matches()) {
|
||||
|
||||
if (Modifier.isStatic(method.getModifiers())) return false;
|
||||
if (!Modifier.isPublic(method.getModifiers())) return false;
|
||||
if (!Void.TYPE.equals(method.getReturnType())) return false;
|
||||
|
||||
// method parameter checks
|
||||
Class[] params = method.getParameterTypes();
|
||||
if (params.length != 1) return false;
|
||||
if (TypeMappingsFactory.TYPE_UNKNOWN == _tmf.getTypeId(params[0])) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a column value from the ResultSet and return it as resultType.
|
||||
*
|
||||
* @param index The column index of the value to extract from the ResultSet.
|
||||
* @param resultType The return type. Defined in TypeMappingsFactory.
|
||||
* @return The extracted value
|
||||
* @throws java.sql.SQLException on error.
|
||||
*/
|
||||
protected Object extractColumnValue(int index, int resultType) throws SQLException {
|
||||
|
||||
switch (resultType) {
|
||||
case TypeMappingsFactory.TYPE_INT:
|
||||
return new Integer(_resultSet.getInt(index));
|
||||
case TypeMappingsFactory.TYPE_LONG:
|
||||
return new Long(_resultSet.getLong(index));
|
||||
case TypeMappingsFactory.TYPE_FLOAT:
|
||||
return new Float(_resultSet.getFloat(index));
|
||||
case TypeMappingsFactory.TYPE_DOUBLE:
|
||||
return new Double(_resultSet.getDouble(index));
|
||||
case TypeMappingsFactory.TYPE_BYTE:
|
||||
return new Byte(_resultSet.getByte(index));
|
||||
case TypeMappingsFactory.TYPE_SHORT:
|
||||
return new Short(_resultSet.getShort(index));
|
||||
case TypeMappingsFactory.TYPE_BOOLEAN:
|
||||
return _resultSet.getBoolean(index) ? Boolean.TRUE : Boolean.FALSE;
|
||||
case TypeMappingsFactory.TYPE_INT_OBJ:
|
||||
{
|
||||
int i = _resultSet.getInt(index);
|
||||
return _resultSet.wasNull() ? null : new Integer(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_LONG_OBJ:
|
||||
{
|
||||
long i = _resultSet.getLong(index);
|
||||
return _resultSet.wasNull() ? null : new Long(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_FLOAT_OBJ:
|
||||
{
|
||||
float i = _resultSet.getFloat(index);
|
||||
return _resultSet.wasNull() ? null : new Float(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_DOUBLE_OBJ:
|
||||
{
|
||||
double i = _resultSet.getDouble(index);
|
||||
return _resultSet.wasNull() ? null : new Double(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_BYTE_OBJ:
|
||||
{
|
||||
byte i = _resultSet.getByte(index);
|
||||
return _resultSet.wasNull() ? null : new Byte(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_SHORT_OBJ:
|
||||
{
|
||||
short i = _resultSet.getShort(index);
|
||||
return _resultSet.wasNull() ? null : new Short(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_BOOLEAN_OBJ:
|
||||
{
|
||||
boolean i = _resultSet.getBoolean(index);
|
||||
return _resultSet.wasNull() ? null : (i ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_STRING:
|
||||
case TypeMappingsFactory.TYPE_XMLBEAN_ENUM:
|
||||
return _resultSet.getString(index);
|
||||
case TypeMappingsFactory.TYPE_BIG_DECIMAL:
|
||||
return _resultSet.getBigDecimal(index);
|
||||
case TypeMappingsFactory.TYPE_BYTES:
|
||||
return _resultSet.getBytes(index);
|
||||
case TypeMappingsFactory.TYPE_TIMESTAMP:
|
||||
{
|
||||
if (null == _cal)
|
||||
return _resultSet.getTimestamp(index);
|
||||
else
|
||||
return _resultSet.getTimestamp(index, _cal);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_TIME:
|
||||
{
|
||||
if (null == _cal)
|
||||
return _resultSet.getTime(index);
|
||||
else
|
||||
return _resultSet.getTime(index, _cal);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_SQLDATE:
|
||||
{
|
||||
if (null == _cal)
|
||||
return _resultSet.getDate(index);
|
||||
else
|
||||
return _resultSet.getDate(index, _cal);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_DATE:
|
||||
{
|
||||
// convert explicity to java.util.Date
|
||||
// 12918 | knex does not return java.sql.Date properly from web service
|
||||
java.sql.Timestamp ts = (null == _cal) ? _resultSet.getTimestamp(index) : _resultSet.getTimestamp(index, _cal);
|
||||
if (null == ts)
|
||||
return null;
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_CALENDAR:
|
||||
{
|
||||
java.sql.Timestamp ts = (null == _cal) ? _resultSet.getTimestamp(index) : _resultSet.getTimestamp(index, _cal);
|
||||
if (null == ts)
|
||||
return null;
|
||||
Calendar c = (null == _cal) ? Calendar.getInstance() : (Calendar) _cal.clone();
|
||||
c.setTimeInMillis(ts.getTime());
|
||||
return c;
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_REF:
|
||||
return _resultSet.getRef(index);
|
||||
case TypeMappingsFactory.TYPE_BLOB:
|
||||
return _resultSet.getBlob(index);
|
||||
case TypeMappingsFactory.TYPE_CLOB:
|
||||
return _resultSet.getClob(index);
|
||||
case TypeMappingsFactory.TYPE_ARRAY:
|
||||
return _resultSet.getArray(index);
|
||||
case TypeMappingsFactory.TYPE_READER:
|
||||
case TypeMappingsFactory.TYPE_STREAM:
|
||||
throw new MapperException("streaming return types are not supported by the JdbcControl; use ResultSet instead");
|
||||
case TypeMappingsFactory.TYPE_STRUCT:
|
||||
case TypeMappingsFactory.TYPE_UNKNOWN:
|
||||
// JAVA_TYPE (could be any), or REF
|
||||
return _resultSet.getObject(index);
|
||||
default:
|
||||
throw new MapperException("internal error: unknown type ID: " + Integer.toString(resultType));
|
||||
}
|
||||
}
|
||||
public interface RowMapper<K,T> {
|
||||
/**
|
||||
* Map a ResultSet row to the return type class
|
||||
* @return An instance of class, if _mapKeyType is not null and _columnCount is 2, return only index 2
|
||||
*/
|
||||
T mapRowToReturnType() throws SQLException;
|
||||
|
||||
/**
|
||||
* key for map
|
||||
* @return index number 1, with type of _mapKeyType
|
||||
* @throws MapperException if _mapKeyType is null
|
||||
*/
|
||||
K getMapKey() throws SQLException;
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public interface RowMapperProvider {
|
||||
<K, T> RowMapper<K, T> getRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.moparisthebest.jdbc.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public class CaseInsensitiveHashMap<String, V> extends HashMap<String, V> {
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
return super.get(key instanceof java.lang.String ? ((java.lang.String) key).toLowerCase() : key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return super.containsKey(key instanceof java.lang.String ? ((java.lang.String) key).toLowerCase() : key);
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import com.moparisthebest.jdbc.dto.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.*;
|
||||
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.fieldPerson1;
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.getConnection;
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.personRegular;
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class CleaningQueryMapperTest {
|
||||
|
||||
private static Connection conn;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Throwable {
|
||||
conn = getConnection();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() throws Throwable {
|
||||
tryClose(conn);
|
||||
}
|
||||
|
||||
protected QueryMapper qm;
|
||||
protected final ResultSetMapper rsm;
|
||||
|
||||
public CleaningQueryMapperTest(final ResultSetMapper rsm) {
|
||||
this.rsm = rsm;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void open() {
|
||||
this.qm = new QueryMapper(conn, rsm);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
tryClose(qm);
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name="{0}")
|
||||
public static Collection<Object[]> getParameters()
|
||||
{
|
||||
final Cleaner<FieldPerson> personCleaner = new Cleaner<FieldPerson>() {
|
||||
@Override
|
||||
public FieldPerson clean(final FieldPerson dto) {
|
||||
dto.firstName += " " + dto.lastName;
|
||||
dto.lastName = null;
|
||||
return dto;
|
||||
}
|
||||
};
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ new CleaningResultSetMapper<FieldPerson>(personCleaner) },
|
||||
{ new CleaningCachingResultSetMapper<FieldPerson>(personCleaner) },
|
||||
{ new CleaningCompilingResultSetMapper<FieldPerson>(personCleaner) },
|
||||
});
|
||||
}
|
||||
|
||||
// fields
|
||||
|
||||
@Test
|
||||
public void testFieldRegularPerson() throws Throwable {
|
||||
final Person expected = fieldPerson1;
|
||||
final Person actual = qm.toObject(personRegular, expected.getClass(), expected.getPersonNo());
|
||||
assertEquals(expected.getFirstName() + " " + expected.getLastName(), actual.getFirstName());
|
||||
assertNull(actual.getLastName());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue