Mybatis Advanced Custom TypeHandler

In actual application development, it is inevitable that there will be some requirements to customize a TypeHandler, such as such a requirement: the gender transmitted from the front end is male and female, but the field defined by the database is of type tinyint (1: male 2: female). At this point, you can customize an age type processor for conversion.

Define 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?"男":"女";
     }
}

There are two annotations involved here:

  1. @MappedTypes : Specifies a list of Java types to associate with. If it is also specified in the javaType attribute, the configuration on the annotation will be ignored.
  2. @MappedJdbcTypes : Specifies a list of JDBC types to associate with. If it is also specified in the jdbcType attribute, the configuration on the annotation will be ignored.

Configure Mybatis configuration file

Configure the fields in the mapper's xml file

Through the above configuration, the data conversion of the gender field can be realized. You can try it with the source code.

How to execute TypeHandler in source code

Now that you can use TypeHandler, you must know the execution principle. How the type handler converts JDBC type and Java type in Mybatis, the following will introduce in detail from the perspective of source code.

How to convert input parameters

It must happen in the process of setting parameters. The detailed code is in the parameterize() method in PreparedStatementHandler. This method is the method of setting parameters. The source code is as follows:

What is actually executed is the setParameters method in DefaultParameterHandler, as follows:

From the source code above, we can know: typeHandler.setParameter(ps, i + 1,value, jdbcType); is to call the method of setting parameters in the type handler to convert the Java type to the JDBC type.

how the result is converted

This process must happen in the process of executing the query statement, and the ResultSetHandler component is to process the query result, so it must happen in a certain method of this component. After the PreparedStatementHandler executes the query, it calls the handleResultSets() method in the ResultSetHandler to process the results as follows:

Finally, the getResult() method in TypeHandler is called in the getPropertyMappingValue() method in DefaultResultSetHandler, as follows:

Extension: Mybatis provides many default processors

Think about what other scenarios this feature can be used for?

Guess you like

Origin blog.csdn.net/lzzyok/article/details/128489060