MyBatis--自定义TypeHandler

柔光的暖阳◎ 2021-08-13 12:33 480阅读 0赞

自定义TypeHandler

要实现 typeHandler 就需要去实现接口 typeHandler,或者继承 BaseTypeHandler(实际上,BaseTypeHandler 实现了 typeHandler 接口)。

自定义String类型的TypeHandler:

  1. import java.sql.CallableStatement;
  2. import java.sql.PreparedStatement;
  3. import java.sql.SQLException;
  4. import java.sql.ResultSet;
  5. import org.apache.ibatis.type.JdbcType;
  6. import org.apache.ibatis.type.TypeHandler;
  7. import org.apache.log4j.Logger;
  8. public class MyTypeHandler implements TypeHandler<String> {
  9. Logger logger = Logger.getLogger(MyTypeHandler.class);
  10. @Override
  11. public void setParameter(PreparedStatement ps, int i, String parameter,
  12. JdbcType jdbcType) throws SQLException {
  13. logger.info("设置 string 参数【" + parameter + "】");
  14. ps.setString(i, parameter);
  15. }
  16. @Override
  17. public String getResult(ResultSet rs, String columnName)
  18. throws SQLException {
  19. String result = rs.getString(columnName);
  20. logger.info("读取 string 参数 1 【" + result + "】");
  21. return result;
  22. }
  23. @Override
  24. public String getResult(ResultSet rs, int columnIndex) throws SQLException {
  25. String result = rs.getString(columnIndex);
  26. logger.info("读取string 参数 2【" + result + "】");
  27. return result;
  28. }
  29. @Override
  30. public String getResult(CallableStatement cs, int columnIndex)
  31. throws SQLException {
  32. String result = cs.getString(columnIndex);
  33. logger.info("读取 string 参数 3 【" + result + "】");
  34. return result;
  35. }
  36. }

定义的 typeHandler 泛型为 String,显然我们要把数据库的数据类型转化为 String 型,然后实现设置参数和获取结果集的方法。但是这个时候还没有启用 typeHandler,它还需要做如下所示的配置。

  1. <typeHandlers>
  2. <typeHandler jdbcType="VARCHAR" javaType="string" handler="com.mybatis.test.MyTypeHandler"/>
  3. </typeHandlers>

配置完成后系统才会读取它,这样注册后,当 jdbcType 和 javaType 能与 MyTypeHandler 对应的时候,它就会启动 MyTypeHandler。有时候还可以显式启用 typeHandler,一般而言启用这个 typeHandler 有两种方式,如下所示。

  1. ....
  2. <resultMap id="roleMapper" type="role">
  3. <result property="id" column="id"/>
  4. <result property="roleName" column="role_name" jdbcType="VARCHAR" javaType="string"/>
  5. <result property="note" column="note" typeHandler=" com.mybatis.test.MyTypeHandler"/>
  6. </resultMap>
  7. <select id="getRole" parameterType="long" resultMap="roleMapper">
  8. select id,role_name,note from t_role where id = #{id}
  9. </select>
  10. <select id="findRoles" parameterType="string" resultMap="roleMapper">
  11. select id, role_name, note from t_role
  12. where role_name like concat('%',#{roleName, jdbcType=VARCHAR,
  13. javaType=string}, '%')
  14. </select>
  15. <select id="findRoles2" parameterType="string" resultMap="roleMapper">
  16. select id, role_name, note from t_role
  17. where note like concat ('%', # {note, typeHandler=com.mybatis.test.MyTypeHandler},'%')
  18. </select>
  19. ......

注意,要么指定了与自定义 typeHandler 一致的 jdbcType 和 javaType,要么直接使用 typeHandler 指定具体的实现类。

在一些因为数据库返回为空导致无法断定采用哪个 typeHandler 来处理,而又没有注册对应的 javaType 的 typeHandler 时,MyBatis 无法知道使用哪个 typeHandler 转换数据,我们可以采用这样的方式来确定采用哪个 typeHandler 处理,这样就不会有异常出现了。

有时候由于枚举类型很多,系统需要的 typeHandler 也会很多,如果采用配置也会很麻烦,这个时候可以考虑使用包扫描的形式,那么就需要按照以下代码配置了。

  1. <typeHandlertype>
  2. <package name="com.mybatis.test"/>
  3. </typeHandlertype>

只是这样就没法指定 jdbcType 和 javaType 了,不过我们可以使用注解来处理它们。我们把 MyTypeHandler 的声明修改一下,如下所示。

  1. @MappedTypes(String.class)
  2. @MappedjdbcTypes(jdbcType.VARCHAR)
  3. public class MyTypeHandler implements TypeHandler<String>{
  4. ......
  5. }

发表评论

表情:
评论列表 (有 0 条评论,480人围观)

还没有评论,来说两句吧...

相关阅读

    相关 定义TypeHandler

    在大部分的场景下,MyBatis 的 typeHandler 就能应付一般的场景,但是有时候不够用。比如使用枚举的时候,枚举有特殊的转化规则,这个时候需要自定义 typeHan