1 概述
BaseBuilder家族的主要作用就是处理配置文件的内容,包括mapper配置文件和config文件,在这里我们有必要首先对其基类进行简单地说明。
2 属性
2.1 configuration
持有配置文件对象,方便解析配置文件后对数据进行设置。
2.2 typeAliasRegistry
类别名注册器,里面持有类别名和类的键值对。
2.3 typeHandlerRegistry
类型处理注册器。我们来看一下类型处理注册器里面的详细实现。
2.3.1 属性
//JDBC类型和类型处理器的映射关系,这里用到EnumMap,这个EnumMap的键必须是枚举类中的值
private final Map<JdbcType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new EnumMap<JdbcType, TypeHandler<?>>(JdbcType.class);
//类,JDBC类型和类型处理器的映射关系
private final Map<Type, Map<JdbcType, TypeHandler<?>>> TYPE_HANDLER_MAP = new HashMap<Type, Map<JdbcType, TypeHandler<?>>>();
//如果类没有对应的类型处理器就是用这个类型处理器
private final TypeHandler<Object> UNKNOWN_TYPE_HANDLER = new UnknownTypeHandler(this);
//普通类和类型处理器的映射关系
private final Map<Class<?>, TypeHandler<?>> ALL_TYPE_HANDLERS_MAP = new HashMap<Class<?>, TypeHandler<?>>();
2.3.2 核心函数
(1) java type + handler
public <T> void register(Class<T> javaType, TypeHandler<? extends T> typeHandler) {
register((Type) javaType, typeHandler);
}
我们可以看见这个函数里面将javaType进行向上转型成Type类型后,然后调用了另一个函数。
private <T> void register(Type javaType, TypeHandler<? extends T> typeHandler) {
//获取handler对应的注解MappedJdbcTypes,这个注解标记了类型处理器对应的jdbcType
MappedJdbcTypes mappedJdbcTypes = typeHandler.getClass().getAnnotation(MappedJdbcTypes.class);
if (mappedJdbcTypes != null) {
//遍历jdbcType数组,进行jdbc类型,java类型和类型处理器注册
for (JdbcType handledJdbcType : mappedJdbcTypes.value()) {
register(javaType, handledJdbcType, typeHandler);
}
//空类型注册
if (mappedJdbcTypes.includeNullJdbcType()) {
register(javaType, null, typeHandler);
}
} else {
register(javaType, null, typeHandler);
}
}
可以看出来,最终都是调用了如下函数:
private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler) {
if (javaType != null) {
//获取java类型对应的jdbc类型和类型处理器
Map<JdbcType, TypeHandler<?>> map = TYPE_HANDLER_MAP.get(javaType);
if (map == null) {
map = new HashMap<JdbcType, TypeHandler<?>>();
//添加java类型和类型处理器的映射关系
TYPE_HANDLER_MAP.put(javaType, map);
}
//添加jdbc类型和类型处理器的映射关系
map.put(jdbcType, handler);
}
//添加类型处理的类和类型处理器映射关系
ALL_TYPE_HANDLERS_MAP.put(handler.getClass(), handler);
}
(2) jdbcType + handler
public void register(JdbcType jdbcType, TypeHandler<?> handler) {
JDBC_TYPE_HANDLER_MAP.put(jdbcType, handler);
}
这个函数其实就是直接将jdbc类型和类型处理器的map中加入映射关系。
其余的函数我们这里就不进行进一步分析了,大同小异。
3 函数
上面我们分析了BaseBuilder的属性,现在我们针对重要的函数进行分析。
3.1 将字符串转换成对应的数据类型
protected Pattern parseExpression(String regex, String defaultValue) {
return Pattern.compile(regex == null ? defaultValue : regex);
}
protected Boolean booleanValueOf(String value, Boolean defaultValue) {
return value == null ? defaultValue : Boolean.valueOf(value);
}
protected Integer integerValueOf(String value, Integer defaultValue) {
return value == null ? defaultValue : Integer.valueOf(value);
}
protected Set<String> stringSetValueOf(String value, String defaultValue) {
value = (value == null ? defaultValue : value);
return new HashSet<String>(Arrays.asList(value.split(",")));
}
3.2 根据别名获取对应的jdbc类型
protected JdbcType resolveJdbcType(String alias) {
if (alias == null) {
return null;
}
try {
return JdbcType.valueOf(alias);
} catch (IllegalArgumentException e) {
throw new BuilderException("Error resolving JdbcType. Cause: " + e, e);
}
}
3.3 根据别名获取结果集类型
protected ResultSetType resolveResultSetType(String alias) {
if (alias == null) {
return null;
}
try {
return ResultSetType.valueOf(alias);
} catch (IllegalArgumentException e) {
throw new BuilderException("Error resolving ResultSetType. Cause: " + e, e);
}
}
3.4 根据别名获取参数类型
protected ParameterMode resolveParameterMode(String alias) {
if (alias == null) {
return null;
}
try {
return ParameterMode.valueOf(alias);
} catch (IllegalArgumentException e) {
throw new BuilderException("Error resolving ParameterMode. Cause: " + e, e);
}
}
我们查看ParameterMode枚举类,可以看见参数类型有 IN, OUT, INOUT。
针对余下的函数这里就不详细说明了,其实就是调用其属性对应的函数。
后面继续更新对Mybatis源码的分析,欢迎交流。