Mybatis from entry to the proficient use of --TypeHandler (18)

A, TypeHandler

TypeHandler processor mutual conversion between a JdcbType Mybatis The javaType and provided, for converting during transmission the reference value and return, in result, id return value map such label, generally does not require conversion, because Mybatis has provided more than adequate and commonly used TypeHandler.

 

Second, the case

Case Description:

For enumerated conversion, Mybatis is not available, we need a database and sex gender and 0 is converted to an enumeration value set to the corresponding property.

User entity class:

public class User {
    private Integer id;

    private String userName;

    private String realName;

    private Sex sex;

    private String mobile;

    private String email;

    private String note;

    private Integer positionId;
}

Sex enumeration class:

public enum Sex {

  MALE(1, "男"),
  FEMALE(0, "女");

  Sex(int id, String name) {
    this.id = id;
    this.name = name;
  }

  private int id;
  private String name;

  public static Sex getSexById(int id) {
    for (Sex sex : Sex.values()) {
      if (sex.getId() == id) {
        return sex;
      }
    }
    return null;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Sex{" +
      "id=" + id +
      ", name='" + name + '\'' +
      '}';
  }
}

TypeHandler implementation class:

@MappedJdbcTypes({JdbcType.CHAR,JdbcType.VARCHAR})
@MappedTypes(Sex.class)
public class SexTypeHandler extends BaseTypeHandler<Sex> {

    /**
     * 参数设置
     * @param ps Statement
     * @param i 参数位置
     * @param parameter 参数
     * @param jdbcType jdbc类型
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Sex parameter, JdbcType jdbcType) throws SQLException {
        Integer sex = parameter.getId();
        ps.setString(i,sex.toString());
    }

    /**
     * 返回值处理
     * @param rs ResultSet结果集
     * @param columnName 当前列名
     * @return Sex
     * @throws SQLException
     */
    @Override
    public Sex getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Integer id = Integer.valueOf(rs.getString(columnName));
        return Sex.getSexById(id);
    }

    /**
     * 返回值处理
     * @param rs 结果集
     * @param columnIndex 当前需要转为的列的位置
     * @return Sex
     * @throws SQLException
     */
    @Override
    public Sex getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Integer id = Integer.valueOf(rs.getInt(columnIndex));
        return Sex.getSexById(id);
    }

    /**
     * 存储过程结果处理
     * @param cs
     * @param columnIndex 列的位置
     * @return 映射到属性上的值
     * @throws SQLException
     */
    @Override
    public Sex getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Integer id = Integer.valueOf(cs.getInt(columnIndex));
        return Sex.getSexById(id);
    }
}

mapper mapping file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.my.mapper.UserMapper">

  <resultMap id="BaseResultMap" type="com.my.entity.User">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="user_name" jdbcType="VARCHAR" property="userName" />
    <result column="real_name" jdbcType="VARCHAR" property="realName" />
    <!--  typeHandler指明使用的类型转换器,也可以不写会根据属性声明查找  -->
    <result column="sex" jdbcType="CHAR" property="sex" typeHandler="com.my.typehandler.SexTypeHandler"/>
    <result column="mobile" jdbcType="VARCHAR" property="mobile" />
    <result column="email" jdbcType="VARCHAR" property="email" />
    <result column="note" jdbcType="VARCHAR" property="note" />
    <result column="position_id" jdbcType="INTEGER" property="positionId" />
  </resultMap>

  <sql id="Base_Column_List">
    id, user_name, real_name, sex, mobile, email, note, position_id
  </sql>

  <select id="selectBySex" resultMap="BaseResultMap" parameterType="com.my.enums.Sex">
    select
    <include refid="Base_Column_List" />
    from user
    where sex = #{sex}
  </select>
</mapper>

Mybatis profile:

    <typeHandlers>
<!--    可以在typeHandler标签上写javaType和jdbcType    -->
<!--        <typeHandler handler="com.my.typehandler.SexTypeHandler" javaType="com.my.enums.Sex" jdbcType="CHAR"></typeHandler>-->
                <typeHandler handler="com.my.typehandler.SexTypeHandler"></typeHandler>
    </typeHandlers>

Test code:

public class MybatisTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void init() throws IOException {
        String resource = "mybatis-config.xml";
        //1.使用mybatis的工具读取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //2.创建sqlSessionFactory
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        inputStream.close();
    }

    /**
     * 测试TypeHandler
     */
    @Test
    public void testTypeHandler() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectBySex(Sex.FEMALE);
        System.out.println(users);
        sqlSession.close();
    }

}

 

Third, use the steps

step:

1. Inheritance BaseTypeHandler <T> class or implement TypeHandler <T> interface, usually inherit BaseTypeHandler <T> class, T refers to the generic conversion type java

2. The method of rewriting 4, hereinafter be described

3. Sign in Mybatis profile TypeHandler

4. Add @MappedJdbcTypes @MappedTypes and annotations on its interface implementation class and explanatory notes converted javaType jdbcType

 

BaseTypeHandler <T> override the method described:

1..void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType):

    This method is called when the attribute setting, when the passed parameter type is T method, how the conversion process, i is the column number

2.T getNullableResult(ResultSet rs, String columnName):

    This method is called when the property is set to the return value, the return value when the property type is T, and jdbc types match, how conversion processing, a column name columnName

3.T getNullableResult(ResultSet rs, int columnIndex):

    This method is called when the property is set to the return value, the return value when the property type is T, and jdbc types match, how the conversion process, the column number columnName

4.T getNullableResult(CallableStatement cs, int columnIndex):

    This method is called when the property is set to the return value, the return value when the property type is T, and jdbc types match, how the conversion process, the column number columnName, the method is a stored procedure in the operation process.

 

@MappedJdbcTypes Description

The annotation used in TypeHandler <T> implementation class, indicating that converts JDBC type and may be a plurality of write.

 

@MappedTypes Description

The annotation used in TypeHandler <T> implementation class, Java indicate the required conversion type, generally written only one.

 

Fourth, supplement

1.BaseTypeHandler <T> class also implements TypeHandler <T> interface, and to do some packages, custom type converter class can inherit.

2.id, typeHandler tag attributes result in dispensable, because it finds based on the type of property declaration.

3. When the registration type converter, you can define good and javaType jdbcType in Mybatis profile, but is generally defined on the interface implementation class.

 

Published 61 original articles · won praise 81 · Views 100,000 +

Guess you like

Origin blog.csdn.net/m0_37914588/article/details/104757034