简介
在上篇文章中,我们介绍了TypeHandler的简单使用和解析了TypeHandler的处理核心,这篇文章中我们接着看到TypeHandler是如注册和获取使用的
源码解析
TypeHandler注册
typeHandler注册的函数代码如下:
- 根据JavaType放入第一层Map
- 根据jdbcType放入第二层Map
configuration.getTypeHandlerRegistry().register(String[].class, JdbcType.VARCHAR, StringArrayTypeHandler.class);
private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler) {
if (javaType != null) {
Map<JdbcType, TypeHandler<?>> map = typeHandlerMap.get(javaType);
if (map == null || map == NULL_TYPE_HANDLER_MAP) {
map = new HashMap<>();
}
map.put(jdbcType, handler);
typeHandlerMap.put(javaType, map);
}
allTypeHandlersMap.put(handler.getClass(), handler);
}
TypeHandler获取
在探索中,我们发现是在Mapper初始化的过程就会去获取TypeHandler了,在示例代码中我们调用了函数:addMapper
在该函数中,我们看到了我们熟悉的(前面文章分析过,Sql执行其实就是从Mapper代理类开始的)MapperProxy相关的东西
public <T> void addMapper(Class<T> type) {
if (type.isInterface()) {
if (hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
// 生成我们熟悉的Mapper代理类
knownMappers.put(type, new MapperProxyFactory<>(type));
// It's important that the type is added before the parser is run
// otherwise the binding may automatically be attempted by the
// mapper parser. If the type is already known, it won't try.
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
// 进行解析
parser.parse();
loadCompleted = true;
} finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
}
跟踪下面,我们看到SQLSource生成的相关代码,ParameterMapper就是从SQLSource带下去的
void parseStatement(Method method) {
......
getAnnotationWrapper(method, true, statementAnnotationTypes).ifPresent(statementAnnotation -> {
final SqlSource sqlSource = buildSqlSource(statementAnnotation.getAnnotation(), parameterTypeClass, languageDriver, method);
......
});
}
public SqlSource createSqlSource(Configuration configuration, String script, Class