您的位置:首页 > 编程语言 > Java开发

MyBatis整合Spring的实现(5)

2015-10-25 00:00 483 查看
摘要: MyBatis类型处理器------TypeHandlerRegistry

分析
MyBatis整合Spring的实现(1)中代码实现的4.4拦截器后面文章根据具体例子分析,分析4.5、4.6可以知道,这2个都是去生成类型管理器TypeHandlerRegistry类,下面就来分析代码。
1 属性
这里的属性都是定义基本的类型,所以我们针对每个Map属性,挑选出一条来进行分析。
1.1 reversePrimitiveMap
private static final Map<Class<?>, Class<?>> reversePrimitiveMap = new HashMap<Class<?>, 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);
}
};

首先是原始类型的对象对应原始类型的Class。

1.2 JDBC类型对应的类型处理器------JDBC_TYPE_HANDLER_MAP

private final Map<JdbcType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new EnumMap<JdbcType, TypeHandler<?>>(JdbcType.class);
register(JdbcType.CHAR, new StringTypeHandler());

上面就是数据库中CHAR类型,对应StringTypeHandler处理器。

1.3 JAVA类型、数据库类型、处理器对应MAP------TYPE_HANDLER_MAP

private final Map<Type, Map<JdbcType, TypeHandler<?>>> TYPE_HANDLER_MAP = new HashMap<Type, Map<JdbcType, TypeHandler<?>>>();
register(String.class, JdbcType.CHAR, new StringTypeHandler());
private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler) {
if (javaType != null) {
Map<JdbcType, TypeHandler<?>> map = TYPE_HANDLER_MAP.get(javaType);
if (map == null) {
map = new HashMap<JdbcType, TypeHandler<?>>();
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);
}

上面就是JAVA类型为String,数据库类型为CHAR,对应StringTypeHandler处理器。

1.4 未知处理类型------UNKNOWN_TYPE_HANDLER

private final TypeHandler<Object> UNKNOWN_TYPE_HANDLER = new UnknownTypeHandler(this);
register(Object.class, UNKNOWN_TYPE_HANDLER);
register(Object.class, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
register(JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);

未知类型处理比较少,就全部列出来,也就是最大范围,Object是所有类的父类。

1.5 处理器本身------ALL_TYPE_HANDLERS_MAP

private final Map<Class<?>, TypeHandler<?>> ALL_TYPE_HANDLERS_MAP = new HashMap<Class<?>, TypeHandler<?>>();

本文1.3就已经有这部分代码的处理,把处理器的Class作为Map的key,value为处理器本身。

2 类型处理器作用------StringTypeHandler

处理器有很多,这里只选择一个来进行分析。

2.1 父类BaseTypeHandler



上图是父类BaseTypeHandler,使用了泛型,并继承TypeReference,实现TypeHandler。

2.2 接口TypeHandler



写过底层JDBC代码的朋友都清楚,这几个方法是做什么的。

2.2.1 setParameter

当JAVA代码中使用PreparedStatement时,因为是预编译,所以值是后来设置的,这个方法就是对相应的?设置值。

2.2.2 T getResult(ResultSet rs, String columnName)

方法是通过最后的列名获取相应的列的值。

2.2.3 T getResult(ResultSet rs, int columnIndex)

方法是通过顺序获取相应的列的值。

2.2.4 T getResult(CallableStatement cs, int columnIndex)

方法是存储过程调用返回的结果,也是通过顺序获取相应的列的值。

2.3 TypeReference

不清楚,以后再补充。。。

3 类型管理器,Spring配置属性------包/类

if (hasLength(this.typeHandlersPackage)) {
String[] typeHandlersPackageArray = tokenizeToStringArray(this.typeHandlersPackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
for (String packageToScan : typeHandlersPackageArray) {
configuration.getTypeHandlerRegistry().register(packageToScan);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Scanned package: '" + packageToScan + "' for type handlers");
}
}
}
if (!isEmpty(this.typeHandlers)) {
for (TypeHandler<?> typeHandler : this.typeHandlers) {
configuration.getTypeHandlerRegistry().register(typeHandler);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Registered type handler: '" + typeHandler + "'");
}
}
}

根据前一章,这里很好分析,代码做了哪些事情。这里不再过多的分析。

总结:

类型处理器的作用,就是在SQL设置值(PreparedStatement)时,把JAVA类型的对象转换成数据库类型。

在SQL执行结果返回时,把数据库类型的数据转换成JAVA类型对象。

实际应用中,默认的类型处理器基本已经够用。

这里只是针对字符串类型进行分析,其它类型也都一样,可以自行看看源码。如果对JDBC不太清楚,可以找找资料,写个测试类,看看JDBC代码。能更好的了解,MyBatis这里的设计理念。

注:类型也支持注解方式,作者没有使用过注解,也就没有分析关于注解方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: