Mybatis进阶之自定义TypeHandler

实际应用开发中的难免会有一些需求要自定义一个TypeHandler ,比如这样一个需求:前端传来的性别是 男, 女,但是数据库定义的字段却是tinyint 类型( 1:男 2:女)。此时可以自定义一个年龄的类型处理器,进行转换。

定义TypeHandler

package com.mtaite.study.mybatis.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.StringUtils;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


@MappedJdbcTypes(JdbcType.INTEGER)
@MappedTypes(String.class)
public class GenderTypeHandler extends BaseTypeHandler {

      //设置参数,这里将Java的String类型转换为JDBC的Integer类型
      @Override
      public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
           ps.setInt(i, parameter.toString().equals("男")? 1:2);
       }
      //  以下三个参数都是将查询的结果转换
      @Override
      public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
          return rs.getInt(columnName)==1?"男":"女";
     }
     @Override
     public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
       return rs.getInt(columnIndex)==1?"男":"女";
     }
     @Override
     public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
          return cs.getInt(columnIndex)==1?"男":"女";
     }
}

这里涉及到两个注解:

  1. @MappedTypes :指定与其关联的 Java 类型列表。 如果在 javaType 属性中也同时指定,则注解上的配置将被忽略。
  2. @MappedJdbcTypes :指定与其关联的 JDBC 类型列表。 如果在jdbcType 属性中也同时指定,则注解上的配置将被忽略。

配置Mybatis配置文件

配置mapper的xml文件中的字段

通过上面的配置就可以实现性别字段的数据转换了,可以拿源代码试试哦。

源码中如何执行TypeHandler

既然会使用TypeHandler 了,那么肯定要知道其中的执行原理了,在Mybatis中类型处理器是如何在JDBC 类型和Java 类型进行转换的,下面的将从源码角度详细介绍。

入参如何转换

肯定是发生在设置参数的过程中,详细的代码在PreparedStatementHandler 中的parameterize() 方法中,这个方法就是设置参数的方法。源码如下:

实际执行的是DefaultParameterHandler 中的setParameters 方法,如下:

从上面的源码中可以知道: typeHandler.setParameter(ps, i + 1,value, jdbcType); 就是调用类型处理器中的设置参数的方法,将Java 类型转换为JDBC 类型。

结果如何转换

这一过程肯定是发生在执行查询语句的过程中,其中的ResultSetHandler 这个组件就是对查询的结果进行处理的,那么肯定是发生在这一组件中的某个方法。 在PreparedStatementHandler 执行查询结束之后,调用的是ResultSetHandler 中的handleResultSets() 方法,对结果进行处理,如下:

最终是在DefaultResultSetHandler 中的getPropertyMappingValue() 方法中调用了TypeHandler 中的getResult() 方法,如下:

扩展:Mybatis提供了许多默认处理器

想想这个功能还可以用于什么场景呢?

猜你喜欢

转载自blog.csdn.net/lzzyok/article/details/128489060