MyBatis 提供了很多默认类型处理器,参考官网地址:链接,除了官网提供的类型处理器,我们也可以自定义类型处理器。

具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承 org.apache.ibatis.type.BaseTypeHandler 类 , 然后可以选择性地将它映射到一个 JDBC 类型。

测试类:com.yjw.demo.TypeHandlerTest

比如我们要自定义一个性别的枚举类型处理器,实现步骤如下所示:

创建类型处理器

定义性别的枚举

  1. /**
  2. * 性格枚举
  3. *
  4. * @author yinjianwei
  5. * @date 2018/09/27
  6. */
  7. public enum Sex {
  8. MALE(1, "男"), FEMALE(2, "女");
  9. private Integer code;
  10. private String value;
  11. private Sex(Integer code, String value) {
  12. this.code = code;
  13. this.value = value;
  14. }
  15. /**
  16. * 根据code获得value
  17. *
  18. * @param code
  19. * @return
  20. */
  21. public static String getValue(Integer code) {
  22. String value = null;
  23. for (Sex sex : Sex.values()) {
  24. if (sex.getCode().equals(code)) {
  25. value = sex.getValue();
  26. }
  27. }
  28. return value;
  29. }
  30. /**
  31. * 根据code获取sex
  32. *
  33. * @param code
  34. * @return
  35. */
  36. public static Sex getSex(Integer code) {
  37. for (Sex sex : Sex.values()) {
  38. if (sex.getCode().equals(code)) {
  39. return sex;
  40. }
  41. }
  42. return null;
  43. }
  44. /**
  45. * @return the code
  46. */
  47. public Integer getCode() {
  48. return code;
  49. }
  50. /**
  51. * @param code the code to set
  52. */
  53. public void setCode(Integer code) {
  54. this.code = code;
  55. }
  56. /**
  57. * @return the value
  58. */
  59. public String getValue() {
  60. return value;
  61. }
  62. /**
  63. * @param value the value to set
  64. */
  65. public void setValue(String value) {
  66. this.value = value;
  67. }
  68. }

创建性别类型处理器 SexEnumTypeHandler

  1. /**
  2. * 性别类型处理器
  3. *
  4. * @author yinjianwei
  5. * @date 2018/09/27
  6. */
  7. public class SexEnumTypeHandler extends BaseTypeHandler<Sex> {
  8. /**
  9. * 入参处理
  10. */
  11. @Override
  12. public void setNonNullParameter(PreparedStatement ps, int i, Sex parameter, JdbcType jdbcType) throws SQLException {
  13. ps.setInt(i, parameter.getCode());
  14. }
  15. /**
  16. * 返回结果处理
  17. */
  18. @Override
  19. public Sex getNullableResult(ResultSet rs, String columnName) throws SQLException {
  20. int code = rs.getInt(columnName);
  21. if (rs.wasNull()) {
  22. return null;
  23. } else {
  24. return Sex.getSex(code);
  25. }
  26. }
  27. /**
  28. * 返回结果处理
  29. */
  30. @Override
  31. public Sex getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  32. int code = rs.getInt(columnIndex);
  33. if (rs.wasNull()) {
  34. return null;
  35. } else {
  36. return Sex.getSex(code);
  37. }
  38. }
  39. /**
  40. * 存储过程返回结果(CallableStatement)处理
  41. */
  42. @Override
  43. public Sex getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  44. int code = cs.getInt(columnIndex);
  45. if (cs.wasNull()) {
  46. return null;
  47. } else {
  48. return Sex.getSex(code);
  49. }
  50. }
  51. }

这里使用的是继承 org.apache.ibatis.type.BaseTypeHandler 类的方式,重写父类的四个方法,分别对入参和返回结果做了类型转换处理。

配置类型处理器

有两种方式配置类型处理器,一种是在 MyBatis 的配置文件中配置,可以实现类型处理器的自动发现;另外一种是显式地为那些 SQL 语句设置要使用的类型处理器。

MyBatis 配置文件中配置

application-dev.yml

  1. mybatis:
  2. type-aliases-package: com.yjw.demo.mybatis.biz.pojo.entity;com.yjw.demo.mybatis.biz.pojo.query
  3. mapper-locations: classpath:mapper/*.xml
  4. configLocation: classpath:mybatis-config.xml
  5. # configuration:
  6. # lazy-loading-enabled: true
  7. # aggressive-lazy-loading: false

mybatis.configLocation:指定 MyBatis 的 XML 配置文件路径。

mybatis-config.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  4. <configuration>
  5. <typeHandlers>
  6. <typeHandler javaType="com.yjw.demo.mybatis.common.constant.Sex"
  7. jdbcType="TINYINT"
  8. handler="com.yjw.demo.mybatis.common.type.SexEnumTypeHandler"/>
  9. </typeHandlers>
  10. </configuration>

mybatis-config.xml 文件配置 typeHandler,通过显示的指定 javaType 和 jdbcType 实现类型处理器的自动发现,比如在调用如下 insert 配置的时候就不需要显示的指定 typeHandler,就可以实现类型转换的功能。

StudentMapper.xml

  1. <insert id="insert" parameterType="studentDO" keyProperty="id" useGeneratedKeys="true">
  2. insert into t_student (name, sex, selfcard_no, note)
  3. values (
  4. #{name,jdbcType=VARCHAR},
  5. #{sex,jdbcType=TINYINT},
  6. #{selfcardNo,jdbcType=BIGINT},
  7. #{note,jdbcType=VARCHAR}
  8. )
  9. </insert>

显示指定类型处理器

如果在 mybatis-config.xml 配置文件中没有配置 typeHandler,可以在各个映射文件中显示配置需要使用的类型处理器,也可以实现类型转换的功能。

比如在调用如下 insert 配置的时候显示的指定 typeHandler。

StudentMapper.xml

  1. <insert id="insert" parameterType="studentDO" keyProperty="id" useGeneratedKeys="true">
  2. insert into t_student (name, sex, selfcard_no, note)
  3. values (
  4. #{name,jdbcType=VARCHAR},
  5. #{sex,jdbcType=TINYINT,typeHandler=com.yjw.demo.mybatis.common.type.SexEnumTypeHandler},
  6. #{selfcardNo,jdbcType=BIGINT},
  7. #{note,jdbcType=VARCHAR}
  8. )
  9. </insert>

上面的例子只展现了入参的类型转换的效果,返回结果的效果参考 com.yjw.demo.mybatis.biz.dao.StudentDao#listByConditions 方法,typeHandler 的配置如下。

  1. <resultMap id="BaseResultMap" type="studentDO">
  2. <id column="id" jdbcType="BIGINT" property="id" />
  3. <result column="name" jdbcType="VARCHAR" property="name" />
  4. <result column="sex" jdbcType="TINYINT" property="sex" />
  5. <!--<result column="sex" jdbcType="TINYINT" property="sex"
  6. typeHandler="com.yjw.demo.mybatis.common.type.SexEnumTypeHandler"/>-->
  7. <result column="selfcard_no" jdbcType="BIGINT" property="selfcardNo" />
  8. <result column="note" jdbcType="VARCHAR" property="note" />
  9. </resultMap>

如果在 MyBatis 的配置文件(mybatis-config.xml)中配置了 typeHandler 了,这里就不需要显示的配置了。

作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/un45v3 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。