Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize TypeHandlerRegistry #2955

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 104 additions & 82 deletions src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,82 +81,100 @@ public TypeHandlerRegistry() {
public TypeHandlerRegistry(Configuration configuration) {
this.unknownTypeHandler = new UnknownTypeHandler(configuration);

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());
BooleanTypeHandler booleanTypeHandler = new BooleanTypeHandler();
register(Boolean.class, booleanTypeHandler);
register(boolean.class, booleanTypeHandler);
register(JdbcType.BOOLEAN, booleanTypeHandler);
register(JdbcType.BIT, booleanTypeHandler);

ByteTypeHandler byteTypeHandler = new ByteTypeHandler();
register(Byte.class, byteTypeHandler);
register(byte.class, byteTypeHandler);
register(JdbcType.TINYINT, byteTypeHandler);

ShortTypeHandler shortTypeHandler = new ShortTypeHandler();
register(Short.class, shortTypeHandler);
register(short.class, shortTypeHandler);
register(JdbcType.SMALLINT, shortTypeHandler);

IntegerTypeHandler integerTypeHandler = new IntegerTypeHandler();
register(Integer.class, integerTypeHandler);
register(int.class, integerTypeHandler);
register(JdbcType.INTEGER, integerTypeHandler);

LongTypeHandler longTypeHandler = new LongTypeHandler();
register(Long.class, longTypeHandler);
register(long.class, longTypeHandler);

FloatTypeHandler floatTypeHandler = new FloatTypeHandler();
register(Float.class, floatTypeHandler);
register(float.class, floatTypeHandler);
register(JdbcType.FLOAT, floatTypeHandler);

DoubleTypeHandler doubleTypeHandler = new DoubleTypeHandler();
register(Double.class, doubleTypeHandler);
register(double.class, doubleTypeHandler);
register(JdbcType.DOUBLE, doubleTypeHandler);

register(Reader.class, new ClobReaderTypeHandler());
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 StringTypeHandler());
register(String.class, JdbcType.LONGVARCHAR, new StringTypeHandler());
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 StringTypeHandler());
register(JdbcType.NVARCHAR, new NStringTypeHandler());
register(JdbcType.NCHAR, new NStringTypeHandler());
register(JdbcType.NCLOB, new NClobTypeHandler());

register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());
register(JdbcType.ARRAY, new ArrayTypeHandler());
StringTypeHandler stringTypeHandler = new StringTypeHandler();
register(String.class, stringTypeHandler);
register(String.class, JdbcType.CHAR, stringTypeHandler);
ClobTypeHandler clobTypeHandler = new ClobTypeHandler();
register(String.class, JdbcType.CLOB, clobTypeHandler);
register(String.class, JdbcType.VARCHAR, stringTypeHandler);
register(String.class, JdbcType.LONGVARCHAR, stringTypeHandler);
NStringTypeHandler nStringTypeHandler = new NStringTypeHandler();
register(String.class, JdbcType.NVARCHAR, nStringTypeHandler);
register(String.class, JdbcType.NCHAR, nStringTypeHandler);
NClobTypeHandler nClobTypeHandler = new NClobTypeHandler();
register(String.class, JdbcType.NCLOB, nClobTypeHandler);
register(JdbcType.CHAR, stringTypeHandler);
register(JdbcType.VARCHAR, stringTypeHandler);
register(JdbcType.CLOB, clobTypeHandler);
register(JdbcType.LONGVARCHAR, stringTypeHandler);
register(JdbcType.NVARCHAR, nStringTypeHandler);
register(JdbcType.NCHAR, nStringTypeHandler);
register(JdbcType.NCLOB, nClobTypeHandler);

ArrayTypeHandler arrayTypeHandler = new ArrayTypeHandler();
register(Object.class, JdbcType.ARRAY, arrayTypeHandler);
register(JdbcType.ARRAY, arrayTypeHandler);

register(BigInteger.class, new BigIntegerTypeHandler());
register(JdbcType.BIGINT, new LongTypeHandler());
register(JdbcType.BIGINT, longTypeHandler);

register(BigDecimal.class, new BigDecimalTypeHandler());
register(JdbcType.REAL, new BigDecimalTypeHandler());
register(JdbcType.DECIMAL, new BigDecimalTypeHandler());
register(JdbcType.NUMERIC, new BigDecimalTypeHandler());
BigDecimalTypeHandler bigDecimalTypeHandler = new BigDecimalTypeHandler();
register(BigDecimal.class, bigDecimalTypeHandler);
register(JdbcType.REAL, bigDecimalTypeHandler);
register(JdbcType.DECIMAL, bigDecimalTypeHandler);
register(JdbcType.NUMERIC, bigDecimalTypeHandler);

register(InputStream.class, new BlobInputStreamTypeHandler());
register(Byte[].class, new ByteObjectArrayTypeHandler());
register(Byte[].class, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());
register(Byte[].class, JdbcType.LONGVARBINARY, new BlobByteObjectArrayTypeHandler());
BlobByteObjectArrayTypeHandler blobByteObjectArrayTypeHandler = new BlobByteObjectArrayTypeHandler();
register(Byte[].class, JdbcType.BLOB, blobByteObjectArrayTypeHandler);
register(Byte[].class, JdbcType.LONGVARBINARY, blobByteObjectArrayTypeHandler);
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());
BlobTypeHandler blobTypeHandler = new BlobTypeHandler();
register(byte[].class, JdbcType.BLOB, blobTypeHandler);
register(byte[].class, JdbcType.LONGVARBINARY, blobTypeHandler);
register(JdbcType.LONGVARBINARY, blobTypeHandler);
register(JdbcType.BLOB, blobTypeHandler);

register(Object.class, unknownTypeHandler);
register(Object.class, JdbcType.OTHER, unknownTypeHandler);
register(JdbcType.OTHER, unknownTypeHandler);

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());
DateTypeHandler dateTypeHandler = new DateTypeHandler();
register(Date.class, dateTypeHandler);
DateOnlyTypeHandler dateOnlyTypeHandler = new DateOnlyTypeHandler();
register(Date.class, JdbcType.DATE, dateOnlyTypeHandler);
TimeOnlyTypeHandler timeOnlyTypeHandler = new TimeOnlyTypeHandler();
register(Date.class, JdbcType.TIME, timeOnlyTypeHandler);
register(JdbcType.TIMESTAMP, dateTypeHandler);
register(JdbcType.DATE, dateOnlyTypeHandler);
register(JdbcType.TIME, timeOnlyTypeHandler);

register(java.sql.Date.class, new SqlDateTypeHandler());
register(java.sql.Time.class, new SqlTimeTypeHandler());
Expand All @@ -177,8 +195,9 @@ public TypeHandlerRegistry(Configuration configuration) {
register(JapaneseDate.class, new JapaneseDateTypeHandler());

// issue #273
register(Character.class, new CharacterTypeHandler());
register(char.class, new CharacterTypeHandler());
CharacterTypeHandler characterTypeHandler = new CharacterTypeHandler();
register(Character.class, characterTypeHandler);
register(char.class, characterTypeHandler);
}

/**
Expand Down Expand Up @@ -245,10 +264,10 @@ private <T> TypeHandler<T> getTypeHandler(Type type, JdbcType jdbcType) {
handler = jdbcHandlerMap.get(jdbcType);
if (handler == null) {
handler = jdbcHandlerMap.get(null);
}
if (handler == null) {
// #591
handler = pickSoleHandler(jdbcHandlerMap);
if (handler == null) {
// #591
handler = pickSoleHandler(jdbcHandlerMap);
}
}
}
// type drives generics here
Expand Down Expand Up @@ -280,9 +299,6 @@ private Map<JdbcType, TypeHandler<?>> getJdbcHandlerMap(Type type) {
private Map<JdbcType, TypeHandler<?>> getJdbcHandlerMapForEnumInterfaces(Class<?> clazz, Class<?> enumClazz) {
for (Class<?> iface : clazz.getInterfaces()) {
Map<JdbcType, TypeHandler<?>> jdbcHandlerMap = typeHandlerMap.get(iface);
if (jdbcHandlerMap == null) {
jdbcHandlerMap = getJdbcHandlerMapForEnumInterfaces(iface, enumClazz);
}
if (jdbcHandlerMap != null) {
// Found a type handler registered to a super interface
HashMap<JdbcType, TypeHandler<?>> newMap = new HashMap<>();
Expand All @@ -292,6 +308,10 @@ private Map<JdbcType, TypeHandler<?>> getJdbcHandlerMapForEnumInterfaces(Class<?
}
return newMap;
}
jdbcHandlerMap = getJdbcHandlerMapForEnumInterfaces(iface, enumClazz);
if (jdbcHandlerMap != null) {
return jdbcHandlerMap;
}
}
return null;
}
Expand Down Expand Up @@ -345,18 +365,20 @@ public <T> void register(TypeHandler<T> typeHandler) {
mappedTypeFound = true;
}
}
// @since 3.1.0 - try to auto-discover the mapped type
if (!mappedTypeFound && typeHandler instanceof TypeReference) {
try {
TypeReference<T> typeReference = (TypeReference<T>) typeHandler;
register(typeReference.getRawType(), typeHandler);
mappedTypeFound = true;
} catch (Throwable t) {
// maybe users define the TypeReference with a different type and are not assignable, so just ignore it
}
}
if (!mappedTypeFound) {
register((Class<T>) null, typeHandler);
// @since 3.1.0 - try to auto-discover the mapped type
if (typeHandler instanceof TypeReference) {
try {
TypeReference<T> typeReference = (TypeReference<T>) typeHandler;
register(typeReference.getRawType(), typeHandler);
mappedTypeFound = true;
} catch (Throwable t) {
// maybe users define the TypeReference with a different type and are not assignable, so just ignore it
}
}
if (!mappedTypeFound) {
register((Class<T>) null, typeHandler);
}
}
}

Expand Down