自定义类型转换器
每当MyBatis设置参数到PrepareStatement或者从ResultSet结果集中取值时,就会用到TypeHandler来处理数据库类型与Java类型之间的转换。
mybatis 类型转换器适用于 Java 实体类中的类型和数据库中的类型不对应时。
下图是默认的TypeHandler:

但是,有些操作默认的 TypeHandler 是解决不了的。比如,java类中是一个 list 集合,对应的数据库表字段是 varchar。此时就得使用自定义类型转换器了。
public class User {
private Long userId;
private String userName;
private List<String> favorites;
// 省略setter/getter方法
}
一个用户可能有多个爱好,所以是一个集合,和数据库表中的favorites字段则是 varchar
定义接口方法
public interface UserMapper {
List<User> getAllerUser();
Integer insertUser();
}
创建自定义类型转换器
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
// TypeHandler 的泛型为 要转换参数的类型
public class List2VarcharHandler implements TypeHandler<List<String>> {
/**
* 此方法是在插入时进行设置参数,将 list 转换成 String
* @param ps
* @param i 为JDBC 预编译时设置参数的索引值
* @param parameter 需要转换的参数
* @param jdbcType 要插入 JDBC 的类型
* @throws SQLException
*/
public void setParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
StringBuffer buffer = new StringBuffer();
for(String s : parameter){
buffer.append(s).append(",");
}
// 执行添加sql
ps.setString(i,buffer.toString());
}
/**
* 将查询到的结果,转换成 list
*
* @param rs 查询当前类数据
* @param columnName 查询当前列名称,需要转换的字段
* @return
* @throws SQLException
*/
public List<String> getResult(ResultSet rs, String columnName) throws SQLException {
String string = rs.getString(columnName);
if(string != null){
return Arrays.asList(string.split(","));
}
return null;
}
public List<String> getResult(ResultSet rs, int columnIndex) throws SQLException {
String string = rs.getString(columnIndex);
if(string != null){
return Arrays.asList(string.split(","));
}
return null;
}
public List<String> getResult(CallableStatement cs, int columnIndex) throws SQLException {
String string = cs.getString(columnIndex);
if(string != null){
return Arrays.asList(string.split(","));
}
return null;
}
}
设置UserMapper.XML
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.zxqs.mapper.UserMapper">
<resultMap id="UserResult2" type="top.zxqs.mode.User">
<id property="userId" column="user_id"/>
<result property="userName" column="user_name"/>
<result property="favorites" column="favorites" typeHandler="top.zxqs.handler.List2VarcharHandler"/>
</resultMap>
<select id="selectUser" resultMap="UserResult2">
select * from user
</select>
<insert id="insertUser" parameterType="top.zxqs.mode.User">
insert into user (
<if test="userName != null">user_name,</if>
<if test="favorites != null">favorites</if>
) values (
<if test="userName != null">#{userName},</if>
<if test="favorites != null">#{favorites,typeHandler = top.zxqs.handler.List2VarcharHandler}</if>
)
</insert>
</mapper>
最后进行测试:
@Test
public void insertUser(){
User user = new User();
user.setUserName("zhangsan");
user.setFavorites(Arrays.asList("篮球","足球"));
Integer integer = userMapper.insertUser(user);
sqlSession.commit();
}
@Test
public void selectUser(){
List<User> users = userMapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}