SSM开发实战教程(Spring+Spring MVC+MyBatis)
上QQ阅读APP看书,第一时间看更新

1.7.3 <typeHandlers>标签

<typeHandlers>标签的作用是将传入参数的javaType(Java类型)转换为jdbcType(JDBC类型,对应数据库的数据类型),反之从数据库读出结果(即将jdbcType转换为javaType)。

MyBatis提供了大量默认的内置转换器,可以完成大部分常见的类型转换,但若默认的转换器无法满足要求时,可以自定义转换器。自定义转换器需实现TypeHandler接口或者继承BaseTypeHandler类。创建好后需要进行如下注册:

<typeHandlers>

<typeHandler handler="com.lifeng.utils.MyTypeHandler"/>

</typeHandlers>

其中 handler 属性指定的类 com.lifeng.utils.MyTypeHandler 为自定义的转换器(类),然后<ResultMap>标签中就可以引用这个转换器了。

【注意】上面这段配置代码块必须放在environments前面和typeAliases后面。

自定义转换器实际使用起来比较复杂,还涉及后面的知识点,本书配套资源提供了一个完整项目案例mybatis15供参考,请读者至少学完第2章再回头来学习这个项目案例。

项目案例:复制项目mybatis14为mybatis15,在数据库student表中添加一个列address,类型为VARCHAR,用于存储学生的地址信息,存储地址暂定用“城市,街道”这样的格式。在包com.lifeng.entity下新建一个类Address,用于封装学生的地址信息,该类有city和street两个属性,重写toString()方法,使城市city和街道street以“,”连接,创建带参数的构造方法,输入参数为“城市,街道”格式的字符串,在构造方法中进行拆分,分别给city和street属性赋值。实体类Student中添加一个Address类型的属性address。实现学生信息的查找与添加。

问题分析:数据库中地址列是VARCHAR字符类型,Student类中地址属性是Address对象类型,明显类型不一致,按之前的步骤,是无法正确查询并显示出数据来的,添加数据也一样。所以这里要用到自定义类型转换器,使数据库中的address列的VARCHAR类型能正确地转换映射到Student类的address属性的Address对象类型。(完整代码参见本书配套资源:第1章/typeHandler自定义转换器/mybatis15)

关键步骤如下所示:

package com.lifeng.utils;

import java.sql.CallableStatement;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;

import org.apache.ibatis.type.JdbcType;

import com.lifeng.entity.Address;

public class MyTypeHandler extends BaseTypeHandler<Address> {

@Override

public Address getNullableResult(ResultSet resultSet, String columnName)

throws SQLException {

return new Address(resultSet.getString(columnName));

}

@Override

public Address getNullableResult(ResultSet resultSet, int columnIndex)

throws SQLException {

return new Address(resultSet.getString(columnIndex));

}

@Override

public Address getNullableResult(CallableStatement callableStatement, int columnIndex)

throws SQLException {

return new Address(callableStatement.getString(columnIndex));

}

@Override

public void setNonNullParameter(PreparedStatement preparedStatement, int index,

Address address, JdbcType jdbcType) throws SQLException {

preparedStatement.setString(index, address.toString());

}

}