MyBatis TypeHandler

本文将介绍 SpringBoot 整合 MyBatis 时,自定义 TypeHandler 对数据进行转换的做法。

一、数据转换

对于 MyBatis 来说,在 传入参数返回结果 时都需要将数据在 Java 和 SQL 之间转换。

二、类型转换器

MyBatis 默认提供了类型转换器,可以适用于大部分数据转换场景,因此大多数情况下都不需要配置。对于有些 MyBatis 默认无法支持的场景,可以通过自定义类型转换器来进行数据的转换,其方法是:

实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler

org.apache.ibatis.type.BaseTypeHandler 类举例:

  • 继承类时需要通过泛型来指定要转换的数据的 Java 类型
  • setNonNullParameter(PreparedStatement ps, int i, Integer[] parameter, JdbcType jdbcType):将数据由 Java 转向 SQL
    • PreparedStatement ps:Java 中用于执行 SQL 语句的对象,与 PreparedStatement 的区别在于可以防止 SQL 注入攻击
    • int i:SQL 中参数所在的位置
    • Integer[] parameter:Java 中的数据
    • JdbcType jdbcType:JDBC 类型
  • getNullableResult:将数据由 SQL 转向 Java

三、类型转换器 - 示例

自定义一个类型转换器,负责对类型为 Integer 的数组进行转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class IntegerArray2Varchar extends BaseTypeHandler<Integer[]> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Integer[] parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, Arrays.toString(parameter));
}

/**
* Gets the nullable result.
*
* @param rs the rs
* @param columnName Colunm name, when configuration <code>useColumnLabel</code> is <code>false</code>
* @return the nullable result
* @throws SQLException the SQL exception
*/
@Override
public Integer[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 利用ConvertUtils的convert方法将字符串转化为Integer数组
return (Integer[]) ConvertUtils.convert(rs.getString(columnName), Integer[].class);
}

@Override
public Integer[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// 利用ConvertUtils的convert方法将字符串转化为Integer数组
return (Integer[]) ConvertUtils.convert(rs.getString(columnIndex), Integer[].class);
}

@Override
public Integer[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// 利用ConvertUtils的convert方法将字符串转化为Integer数组
return (Integer[]) ConvertUtils.convert(cs.getString(columnIndex), Integer[].class);
}
}

四、类型转换器的配置

1. 全局配置

可以在 SpringBoot 的配置文件中配置如下:

1
2
mybatis:
type-handlers-package: [typeHandler所在的包]

Springboot 将会扫描并适用包下的所有 typeHandler。

需要注意的是,通过这种方法配置,typeHandler 将会接管所有它能够接管的数据转换。

2. 单独配置

传入参数

传入参数时,在参数占位符处填写如下:

1
#{参数名,typeHandler=全限定类名}

返回结果

在 resultMap 中填写如下:

1
2
3
4
5
<resultMap id="resultMap名" type="类名">
···
<result column="列名" property="属性名" typeHandler="全限定类名"/>
···
</resultMap>

参考