Author: cbegin Date: Sat Dec 5 05:08:06 2009 New Revision: 887495 URL: http://svn.apache.org/viewvc?rev=887495&view=rev Log: iBATIS-700 resultMaps with type derived from java.util.Map need explicit per result javaTypes
Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java?rev=887495&r1=887494&r2=887495&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java Sat Dec 5 05:08:06 2009 @@ -1,6 +1,7 @@ package org.apache.ibatis.type; import java.sql.Types; +import java.util.*; public enum JdbcType { @@ -35,9 +36,20 @@ NCLOB(2011); public final int TYPE_CODE; + private static Map<Integer,JdbcType> codeLookup = new HashMap<Integer,JdbcType>(); + + static { + for (JdbcType type : JdbcType.values()) { + codeLookup.put(type.TYPE_CODE, type); + } + } JdbcType(int code) { this.TYPE_CODE = code; } + static JdbcType forCode(int code) { + return codeLookup.get(code); + } + } Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java?rev=887495&r1=887494&r2=887495&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java Sat Dec 5 05:08:06 2009 @@ -19,51 +19,75 @@ } }; + private final Map<JdbcType, TypeHandler> JDBC_TYPE_HANDLER_MAP = new HashMap<JdbcType, TypeHandler>(); private final Map<Class, Map<JdbcType, TypeHandler>> TYPE_HANDLER_MAP = new HashMap<Class, Map<JdbcType, TypeHandler>>(); private final TypeHandler UNKNOWN_TYPE_HANDLER = new UnknownTypeHandler(this); public TypeHandlerRegistry() { register(Boolean.class, new BooleanTypeHandler()); register(boolean.class, new BooleanTypeHandler()); + register(JdbcType.BOOLEAN, new BooleanTypeHandler()); + register(JdbcType.BIT, new BooleanTypeHandler()); register(Byte.class, new ByteTypeHandler()); register(byte.class, new ByteTypeHandler()); + register(JdbcType.TINYINT, new ByteTypeHandler()); register(Short.class, new ShortTypeHandler()); register(short.class, new ShortTypeHandler()); + register(JdbcType.SMALLINT, new ShortTypeHandler()); register(Integer.class, new IntegerTypeHandler()); register(int.class, new IntegerTypeHandler()); + register(JdbcType.INTEGER, new IntegerTypeHandler()); register(Long.class, new LongTypeHandler()); register(long.class, new LongTypeHandler()); register(Float.class, new FloatTypeHandler()); register(float.class, new FloatTypeHandler()); + register(JdbcType.FLOAT, new FloatTypeHandler()); register(Double.class, new DoubleTypeHandler()); register(double.class, new DoubleTypeHandler()); + register(JdbcType.DOUBLE, new DoubleTypeHandler()); register(String.class, new StringTypeHandler()); register(String.class, JdbcType.CHAR, new StringTypeHandler()); register(String.class, JdbcType.CLOB, new ClobTypeHandler()); + register(String.class, JdbcType.VARCHAR, new ClobTypeHandler()); register(String.class, JdbcType.LONGVARCHAR, new ClobTypeHandler()); register(String.class, JdbcType.NVARCHAR, new NStringTypeHandler()); register(String.class, JdbcType.NCHAR, new NStringTypeHandler()); register(String.class, JdbcType.NCLOB, new NClobTypeHandler()); + register(JdbcType.CHAR, new StringTypeHandler()); + register(JdbcType.VARCHAR, new StringTypeHandler()); + register(JdbcType.CLOB, new ClobTypeHandler()); + register(JdbcType.LONGVARCHAR, new ClobTypeHandler()); + register(JdbcType.NVARCHAR, new NStringTypeHandler()); + register(JdbcType.NCHAR, new NStringTypeHandler()); + register(JdbcType.NCLOB, new NClobTypeHandler()); register(BigDecimal.class, new BigDecimalTypeHandler()); + register(JdbcType.BIGINT, new BigDecimalTypeHandler()); + register(JdbcType.REAL, new BigDecimalTypeHandler()); register(byte[].class, new ByteArrayTypeHandler()); register(byte[].class, JdbcType.BLOB, new BlobTypeHandler()); register(byte[].class, JdbcType.LONGVARBINARY, new BlobTypeHandler()); + register(JdbcType.LONGVARBINARY, new BlobTypeHandler()); + register(JdbcType.BLOB, new BlobTypeHandler()); register(Object.class, UNKNOWN_TYPE_HANDLER); register(Object.class, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER); + register(JdbcType.OTHER, UNKNOWN_TYPE_HANDLER); register(Date.class, new DateTypeHandler()); register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler()); register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler()); + register(JdbcType.TIMESTAMP, new DateTypeHandler()); + register(JdbcType.DATE, new DateOnlyTypeHandler()); + register(JdbcType.TIME, new TimeOnlyTypeHandler()); register(java.sql.Date.class, new SqlDateTypeHandler()); register(java.sql.Time.class, new SqlTimeTypeHandler()); @@ -82,6 +106,10 @@ return getTypeHandler(type, null); } + public TypeHandler getTypeHandler(JdbcType jdbcType) { + return JDBC_TYPE_HANDLER_MAP.get(jdbcType); + } + public TypeHandler getTypeHandler(Class type, JdbcType jdbcType) { Map jdbcHandlerMap = TYPE_HANDLER_MAP.get(type); TypeHandler handler = null; @@ -101,6 +129,10 @@ return UNKNOWN_TYPE_HANDLER; } + public void register(JdbcType jdbcType, TypeHandler handler) { + JDBC_TYPE_HANDLER_MAP.put(jdbcType, handler); + } + public void register(Class type, TypeHandler handler) { register(type, null, handler); } Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java?rev=887495&r1=887494&r2=887495&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java Sat Dec 5 05:08:06 2009 @@ -1,9 +1,9 @@ package org.apache.ibatis.type; -import java.sql.CallableStatement; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import org.apache.ibatis.exceptions.IbatisException; + +import java.sql.*; +import java.util.*; public class UnknownTypeHandler extends BaseTypeHandler { @@ -23,7 +23,8 @@ public Object getNullableResult(ResultSet rs, String columnName) throws SQLException { - return rs.getObject(columnName); + TypeHandler handler = resolveTypeHandler(rs, columnName); + return handler.getResult(rs, columnName); } public Object getNullableResult(CallableStatement cs, int columnIndex) @@ -44,4 +45,31 @@ return handler; } + private TypeHandler resolveTypeHandler(ResultSet rs, String column) { + try { + Map<String,Integer> columnIndexLookup; + columnIndexLookup = new HashMap<String,Integer>(); + ResultSetMetaData rsmd = rs.getMetaData(); + int count = rsmd.getColumnCount(); + for (int i=1; i <= count; i++) { + String name = rsmd.getColumnName(i); + columnIndexLookup.put(name,i); + } + Integer columnIndex = columnIndexLookup.get(column); + TypeHandler handler = null; + if (columnIndex != null) { + int jdbcTypeInt = rsmd.getColumnType(columnIndex); + JdbcType jdbcType = JdbcType.forCode(jdbcTypeInt); + + handler = typeHandlerRegistry.getTypeHandler(jdbcType); + } + if (handler == null || handler instanceof UnknownTypeHandler) { + handler = OBJECT_TYPE_HANDLER; + } + return handler; + } catch (SQLException e) { + throw new TypeException("Error determining JDBC type for column " + column + ". Cause: " + e, e); + } + } + } Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java?rev=887495&r1=887494&r2=887495&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java Sat Dec 5 05:08:06 2009 @@ -3,9 +3,7 @@ import org.jmock.Mockery; import org.jmock.lib.legacy.ClassImposteriser; -import java.sql.CallableStatement; -import java.sql.PreparedStatement; -import java.sql.ResultSet; +import java.sql.*; public abstract class BaseTypeHandlerTest { @@ -18,6 +16,7 @@ protected final ResultSet rs = mockery.mock(ResultSet.class); protected final PreparedStatement ps = mockery.mock(PreparedStatement.class); protected final CallableStatement cs = mockery.mock(CallableStatement.class); + protected final ResultSetMetaData rsmd = mockery.mock(ResultSetMetaData.class); public abstract void shouldSetParameter() throws Exception; Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java?rev=887495&r1=887494&r2=887495&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java Sat Dec 5 05:08:06 2009 @@ -25,9 +25,17 @@ throws Exception { mockery.checking(new Expectations() { { - one(rs).getObject(with(any(String.class))); + one(rs).getMetaData(); + will(returnValue(rsmd)); + one(rsmd).getColumnCount(); + will(returnValue(1)); + one(rsmd).getColumnName(with(any(int.class))); + will(returnValue("column")); + one(rsmd).getColumnType(with(any(int.class))); + will(returnValue(JdbcType.VARCHAR.TYPE_CODE)); + one(rs).getString(with(any(String.class))); will(returnValue("Hello")); - one(rs).wasNull(); + allowing(rs).wasNull(); will(returnValue(false)); } });