/*** typeHandler注册管理类*/
public final classTypeHandlerRegistry {//源码一上来,二话不说,几个大大的HashMap就出现,这不又跟上次讲的typeAliases的注册类似么//基本数据类型与其包装类
private static final Map, Class>> reversePrimitiveMap = new HashMap, Class>>() {private static final long serialVersionUID = 1L;
{
put(Byte.class, byte.class);
put(Short.class, short.class);
put(Integer.class, int.class);
put(Long.class, long.class);
put(Float.class, float.class);
put(Double.class, double.class);
put(Boolean.class, boolean.class);
put(Character.class, char.class);
}
};//这几个MAP不用说就知道存的是什么东西吧,命名的好处
private final Map> JDBC_TYPE_HANDLER_MAP = new EnumMap>(JdbcType.class);private final Map>> TYPE_HANDLER_MAP = new HashMap>>();private final TypeHandler UNKNOWN_TYPE_HANDLER = new UnknownTypeHandler(this);private final Map, TypeHandler>> ALL_TYPE_HANDLERS_MAP = new HashMap, TypeHandler>>();//就像上篇文章讲的typeAliases一样,mybatis也默认给我们注册了不少的typeHandler//具体如下
publicTypeHandlerRegistry() {
register(Boolean.class, newBooleanTypeHandler());
register(boolean.class, newBooleanTypeHandler());
register(JdbcType.BOOLEAN,newBooleanTypeHandler());
register(JdbcType.BIT,newBooleanTypeHandler());
register(Byte.class, newByteTypeHandler());
register(byte.class, newByteTypeHandler());
register(JdbcType.TINYINT,newByteTypeHandler());
register(Short.class, newShortTypeHandler());
register(short.class, newShortTypeHandler());
register(JdbcType.SMALLINT,newShortTypeHandler());
register(Integer.class, newIntegerTypeHandler());
register(int.class, newIntegerTypeHandler());
register(JdbcType.INTEGER,newIntegerTypeHandler());
register(Long.class, newLongTypeHandler());
register(long.class, newLongTypeHandler());
register(Float.class, newFloatTypeHandler());
register(float.class, newFloatTypeHandler());
register(JdbcType.FLOAT,newFloatTypeHandler());
register(Double.class, newDoubleTypeHandler());
register(double.class, newDoubleTypeHandler());
register(JdbcType.DOUBLE,newDoubleTypeHandler());
register(String.class, newStringTypeHandler());
register(String.class, JdbcType.CHAR, newStringTypeHandler());
register(String.class, JdbcType.CLOB, newClobTypeHandler());
register(String.class, JdbcType.VARCHAR, newStringTypeHandler());
register(String.class, JdbcType.LONGVARCHAR, newClobTypeHandler());
register(String.class, JdbcType.NVARCHAR, newNStringTypeHandler());
register(String.class, JdbcType.NCHAR, newNStringTypeHandler());
register(String.class, JdbcType.NCLOB, newNClobTypeHandler());
register(JdbcType.CHAR,newStringTypeHandler());
register(JdbcType.VARCHAR,newStringTypeHandler());
register(JdbcType.CLOB,newClobTypeHandler());
register(JdbcType.LONGVARCHAR,newClobTypeHandler());
register(JdbcType.NVARCHAR,newNStringTypeHandler());
register(JdbcType.NCHAR,newNStringTypeHandler());
register(JdbcType.NCLOB,newNClobTypeHandler());
register(Object.class, JdbcType.ARRAY, newArrayTypeHandler());
register(JdbcType.ARRAY,newArrayTypeHandler());
register(BigInteger.class, newBigIntegerTypeHandler());
register(JdbcType.BIGINT,newLongTypeHandler());
register(BigDecimal.class, newBigDecimalTypeHandler());
register(JdbcType.REAL,newBigDecimalTypeHandler());
register(JdbcType.DECIMAL,newBigDecimalTypeHandler());
register(JdbcType.NUMERIC,newBigDecimalTypeHandler());
register(Byte[].class, newByteObjectArrayTypeHandler());
register(Byte[].class, JdbcType.BLOB, newBlobByteObjectArrayTypeHandler());
register(Byte[].class, JdbcType.LONGVARBINARY, newBlobByteObjectArrayTypeHandler());
register(byte[].class, newByteArrayTypeHandler());
register(byte[].class, JdbcType.BLOB, newBlobTypeHandler());
register(byte[].class, JdbcType.LONGVARBINARY, newBlobTypeHandler());
register(JdbcType.LONGVARBINARY,newBlobTypeHandler());
register(JdbcType.BLOB,newBlobTypeHandler());
register(Object.class, UNKNOWN_TYPE_HANDLER);
register(Object.class, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
register(JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
register(Date.class, newDateTypeHandler());
register(Date.class, JdbcType.DATE, newDateOnlyTypeHandler());
register(Date.class, JdbcType.TIME, newTimeOnlyTypeHandler());
register(JdbcType.TIMESTAMP,newDateTypeHandler());
register(JdbcType.DATE,newDateOnlyTypeHandler());
register(JdbcType.TIME,newTimeOnlyTypeHandler());
register(java.sql.Date.class, newSqlDateTypeHandler());
register(java.sql.Time.class, newSqlTimeTypeHandler());
register(java.sql.Timestamp.class, newSqlTimestampTypeHandler());//issue #273
register(Character.class, newCharacterTypeHandler());
register(char.class, newCharacterTypeHandler());
}public boolean hasTypeHandler(Class>javaType) {return hasTypeHandler(javaType, null);
}public boolean hasTypeHandler(TypeReference>javaTypeReference) {return hasTypeHandler(javaTypeReference, null);
}public boolean hasTypeHandler(Class>javaType, JdbcType jdbcType) {return javaType != null && getTypeHandler((Type) javaType, jdbcType) != null;
}public boolean hasTypeHandler(TypeReference>javaTypeReference, JdbcType jdbcType) {return javaTypeReference != null && getTypeHandler(javaTypeReference, jdbcType) != null;
}public TypeHandler> getMappingTypeHandler(Class extends TypeHandler>>handlerType) {returnALL_TYPE_HANDLERS_MAP.get(handlerType);
}public TypeHandler getTypeHandler(Classtype) {return getTypeHandler((Type) type, null);
}public TypeHandler getTypeHandler(TypeReferencejavaTypeReference) {return getTypeHandler(javaTypeReference, null);
}public TypeHandler>getTypeHandler(JdbcType jdbcType) {returnJDBC_TYPE_HANDLER_MAP.get(jdbcType);
}public TypeHandler getTypeHandler(Classtype, JdbcType jdbcType) {returngetTypeHandler((Type) type, jdbcType);
}public TypeHandler getTypeHandler(TypeReferencejavaTypeReference, JdbcType jdbcType) {returngetTypeHandler(javaTypeReference.getRawType(), jdbcType);
}private TypeHandlergetTypeHandler(Type type, JdbcType jdbcType) {
Map> jdbcHandlerMap =TYPE_HANDLER_MAP.get(type);
TypeHandler> handler = null;if (jdbcHandlerMap != null) {
handler=jdbcHandlerMap.get(jdbcType);if (handler == null) {
handler= jdbcHandlerMap.get(null);
}
}if (handler == null && type != null && type instanceof Class && Enum.class.isAssignableFrom((Class>) type)) {
handler= new EnumTypeHandler((Class>) type);
}
@SuppressWarnings("unchecked")//type drives generics here
TypeHandler returned = (TypeHandler) handler;returnreturned;
}public TypeHandlergetUnknownTypeHandler() {returnUNKNOWN_TYPE_HANDLER;
}public void register(JdbcType jdbcType, TypeHandler>handler) {
JDBC_TYPE_HANDLER_MAP.put(jdbcType, handler);
}//
//REGISTER INSTANCE//
/*** 只配置了typeHandler, 没有配置jdbcType 或者javaType*/@SuppressWarnings("unchecked")public void register(TypeHandlertypeHandler) {boolean mappedTypeFound = false;//在自定义typeHandler的时候,可以加上注解MappedTypes 去指定关联的javaType//因此,此处需要扫描MappedTypes注解
MappedTypes mappedTypes = typeHandler.getClass().getAnnotation(MappedTypes.class);if (mappedTypes != null) {for (Class>handledType : mappedTypes.value()) {
register(handledType, typeHandler);
mappedTypeFound= true;
}
}//@since 3.1.0 - try to auto-discover the mapped type
if (!mappedTypeFound && typeHandler instanceofTypeReference) {try{
TypeReference typeReference = (TypeReference) 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) null, typeHandler);
}
}/*** 配置了typeHandlerhe和javaType*/
public void register(Class javaType, TypeHandler extends T>typeHandler) {
register((Type) javaType, typeHandler);
}private void register(Type javaType, TypeHandler extends T>typeHandler) {//扫描注解MappedJdbcTypes
MappedJdbcTypes mappedJdbcTypes = typeHandler.getClass().getAnnotation(MappedJdbcTypes.class);if (mappedJdbcTypes != null) {for(JdbcType handledJdbcType : mappedJdbcTypes.value()) {
register(javaType, handledJdbcType, typeHandler);
}if(mappedJdbcTypes.includeNullJdbcType()) {
register(javaType,null, typeHandler);
}
}else{
register(javaType,null, typeHandler);
}
}public void register(TypeReference javaTypeReference, TypeHandler extends T>handler) {
register(javaTypeReference.getRawType(), handler);
}/*** typeHandlerhe、javaType、jdbcType都配置了*/
public void register(Class type, JdbcType jdbcType, TypeHandler extends T>handler) {
register((Type) type, jdbcType, handler);
}/*** 注册typeHandler的核心方法
* 就是向Map新增数据而已*/
private void register(Type javaType, JdbcType jdbcType, TypeHandler>handler) {if (javaType != null) {
Map> map =TYPE_HANDLER_MAP.get(javaType);if (map == null) {
map= new HashMap>();
TYPE_HANDLER_MAP.put(javaType, map);
}
map.put(jdbcType, handler);if(reversePrimitiveMap.containsKey(javaType)) {
register(reversePrimitiveMap.get(javaType), jdbcType, handler);
}
}
ALL_TYPE_HANDLERS_MAP.put(handler.getClass(), handler);
}//
//REGISTER CLASS//
//Only handler type
public void register(Class>typeHandlerClass) {boolean mappedTypeFound = false;
MappedTypes mappedTypes= typeHandlerClass.getAnnotation(MappedTypes.class);if (mappedTypes != null) {for (Class>javaTypeClass : mappedTypes.value()) {
register(javaTypeClass, typeHandlerClass);
mappedTypeFound= true;
}
}if (!mappedTypeFound) {
register(getInstance(null, typeHandlerClass));
}
}//java type + handler type
public void register(Class> javaTypeClass, Class>typeHandlerClass) {
register(javaTypeClass, getInstance(javaTypeClass, typeHandlerClass));
}//java type + jdbc type + handler type
public void register(Class> javaTypeClass, JdbcType jdbcType, Class>typeHandlerClass) {
register(javaTypeClass, jdbcType, getInstance(javaTypeClass, typeHandlerClass));
}//Construct a handler (used also from Builders)
@SuppressWarnings("unchecked")public TypeHandler getInstance(Class> javaTypeClass, Class>typeHandlerClass) {if (javaTypeClass != null) {try{
Constructor> c = typeHandlerClass.getConstructor(Class.class);return (TypeHandler) c.newInstance(javaTypeClass);
}catch(NoSuchMethodException ignored) {//ignored
} catch(Exception e) {throw new TypeException("Failed invoking constructor for handler " +typeHandlerClass, e);
}
}try{
Constructor> c =typeHandlerClass.getConstructor();return (TypeHandler) c.newInstance();
}catch(Exception e) {throw new TypeException("Unable to find a usable constructor for " +typeHandlerClass, e);
}
}/*** 根据指定的pacakge去扫描自定义的typeHander,然后注册*/
public voidregister(String packageName) {
ResolverUtil> resolverUtil = new ResolverUtil>();
resolverUtil.find(new ResolverUtil.IsA(TypeHandler.class), packageName);
Set>> handlerSet =resolverUtil.getClasses();for (Class>type : handlerSet) {//Ignore inner classes and interfaces (including package-info.java) and abstract classes
if (!type.isAnonymousClass() && !type.isInterface() && !Modifier.isAbstract(type.getModifiers())) {
register(type);
}
}
}//get information
/*** 通过configuration对象可以获取已注册的所有typeHandler*/
public Collection>getTypeHandlers() {returnCollections.unmodifiableCollection(ALL_TYPE_HANDLERS_MAP.values());
}
}