MyBatis 提供了很多默认类型处理器,参考官网地址:链接,除了官网提供的类型处理器,我们也可以自定义类型处理器。
具体做法为:实现 org.apache.ibatis.type.TypeHandler
接口, 或继承 org.apache.ibatis.type.BaseTypeHandler
类 , 然后可以选择性地将它映射到一个 JDBC 类型。
测试类:com.yjw.demo.TypeHandlerTest
比如我们要自定义一个性别的枚举类型处理器,实现步骤如下所示:
创建类型处理器
定义性别的枚举
/** * 性格枚举 * * @author yinjianwei * @date 2018/09/27 */ public enum Sex { MALE(1, "男"), FEMALE(2, "女"); private Integer code; private String value; private Sex(Integer code, String value) { this.code = code; this.value = value; } /** * 根据code获得value * * @param code * @return */ public static String getValue(Integer code) { String value = null; for (Sex sex : Sex.values()) { if (sex.getCode().equals(code)) { value = sex.getValue(); } } return value; } /** * 根据code获取sex * * @param code * @return */ public static Sex getSex(Integer code) { for (Sex sex : Sex.values()) { if (sex.getCode().equals(code)) { return sex; } } return null; } /** * @return the code */ public Integer getCode() { return code; } /** * @param code the code to set */ public void setCode(Integer code) { this.code = code; } /** * @return the value */ public String getValue() { return value; } /** * @param value the value to set */ public void setValue(String value) { this.value = value; } }
创建性别类型处理器 SexEnumTypeHandler
/** * 性别类型处理器 * * @author yinjianwei * @date 2018/09/27 */ public class SexEnumTypeHandler extends BaseTypeHandler<Sex> { /** * 入参处理 */ @Override public void setNonNullParameter(PreparedStatement ps, int i, Sex parameter, JdbcType jdbcType) throws SQLException { ps.setInt(i, parameter.getCode()); } /** * 返回结果处理 */ @Override public Sex getNullableResult(ResultSet rs, String columnName) throws SQLException { int code = rs.getInt(columnName); if (rs.wasNull()) { return null; } else { return Sex.getSex(code); } } /** * 返回结果处理 */ @Override public Sex getNullableResult(ResultSet rs, int columnIndex) throws SQLException { int code = rs.getInt(columnIndex); if (rs.wasNull()) { return null; } else { return Sex.getSex(code); } } /** * 存储过程返回结果(CallableStatement)处理 */ @Override public Sex getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { int code = cs.getInt(columnIndex); if (cs.wasNull()) { return null; } else { return Sex.getSex(code); } } }
这里使用的是继承 org.apache.ibatis.type.BaseTypeHandler
类的方式,重写父类的四个方法,分别对入参和返回结果做了类型转换处理。
配置类型处理器
有两种方式配置类型处理器,一种是在 MyBatis 的配置文件中配置,可以实现类型处理器的自动发现;另外一种是显式地为那些 SQL 语句设置要使用的类型处理器。
MyBatis 配置文件中配置
application-dev.yml
mybatis: type-aliases-package: com.yjw.demo.mybatis.biz.pojo.entity;com.yjw.demo.mybatis.biz.pojo.query mapper-locations: classpath:mapper/*.xml configLocation: classpath:mybatis-config.xml # configuration: # lazy-loading-enabled: true # aggressive-lazy-loading: false
mybatis.configLocation:指定 MyBatis 的 XML 配置文件路径。
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeHandlers> <typeHandler javaType="com.yjw.demo.mybatis.common.constant.Sex" jdbcType="TINYINT" handler="com.yjw.demo.mybatis.common.type.SexEnumTypeHandler"/> </typeHandlers> </configuration>
mybatis-config.xml 文件配置 typeHandler,通过显示的指定 javaType 和 jdbcType 实现类型处理器的自动发现,比如在调用如下 insert 配置的时候就不需要显示的指定 typeHandler,就可以实现类型转换的功能。
StudentMapper.xml
<insert id="insert" parameterType="studentDO" keyProperty="id" useGeneratedKeys="true"> insert into t_student (name, sex, selfcard_no, note) values ( #{name,jdbcType=VARCHAR}, #{sex,jdbcType=TINYINT}, #{selfcardNo,jdbcType=BIGINT}, #{note,jdbcType=VARCHAR} ) </insert>
显示指定类型处理器
如果在 mybatis-config.xml 配置文件中没有配置 typeHandler,可以在各个映射文件中显示配置需要使用的类型处理器,也可以实现类型转换的功能。
比如在调用如下 insert 配置的时候显示的指定 typeHandler。
StudentMapper.xml
<insert id="insert" parameterType="studentDO" keyProperty="id" useGeneratedKeys="true"> insert into t_student (name, sex, selfcard_no, note) values ( #{name,jdbcType=VARCHAR}, #{sex,jdbcType=TINYINT,typeHandler=com.yjw.demo.mybatis.common.type.SexEnumTypeHandler}, #{selfcardNo,jdbcType=BIGINT}, #{note,jdbcType=VARCHAR} ) </insert>
上面的例子只展现了入参的类型转换的效果,返回结果的效果参考 com.yjw.demo.mybatis.biz.dao.StudentDao#listByConditions 方法,typeHandler 的配置如下。
<resultMap id="BaseResultMap" type="studentDO"> <id column="id" jdbcType="BIGINT" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="sex" jdbcType="TINYINT" property="sex" /> <!--<result column="sex" jdbcType="TINYINT" property="sex" typeHandler="com.yjw.demo.mybatis.common.type.SexEnumTypeHandler"/>--> <result column="selfcard_no" jdbcType="BIGINT" property="selfcardNo" /> <result column="note" jdbcType="VARCHAR" property="note" /> </resultMap>
如果在 MyBatis 的配置文件(mybatis-config.xml)中配置了 typeHandler 了,这里就不需要显示的配置了。
MyBatis 实用篇