Custom TypeHandler

In most scenarios, the typeHandler of MyBatis can handle general scenarios, but sometimes it is not enough. For example, when using an enumeration, the enumeration has special conversion rules. At this time, you need to customize the typeHandler to process it.

From  the typeHandler defined by the system  , we can know that to implement typeHandler, we need to implement interface typeHandler, or inherit BaseTypeHandler (in fact, BaseTypeHandler implements typeHandler interface).

Here we imitate a StringTypeHandler to implement a custom typeHandler—MyTypeHandler, which is only used to implement the interface typeHandler, as shown below.

package com.mybatis.test;

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

import java.sql.ResultSet;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import org.apache.log4j.Logger;

public class MyTypeHandler implements TypeHandler<String> {
    Logger logger = Logger.getLogger(MyTypeHandler.class);

    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter,
            JdbcType jdbcType) throws SQLException {
        logger.info("设置 string 参数【" + parameter + "】");
        ps.setString(i, parameter);
    }

    @Override
    public String getResult(ResultSet rs, String columnName)
            throws SQLException {
        String result = rs.getString(columnName);
        logger.info("读取 string 参数 1 【" + result + "】");
        return result;
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        String result = rs.getString(columnIndex);
        logger.info("读取string 参数 2【" + result + "】");
        return result;
    }

    @Override
    public String getResult(CallableStatement cs, int columnIndex)
            throws SQLException {
        String result = cs.getString(columnIndex);
        logger.info("Read string parameter 3 【" + result + "】"); 
        return result; 
    } 
}

The generic type of the defined typeHandler is String, obviously we need to convert the data type of the database into String type, and then realize the method of setting parameters and obtaining the result set. However, typeHandler has not been enabled at this time, and it needs to be configured as shown below.

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

The system will read it after the configuration is completed, so after registration, when jdbcType and javaType can correspond to MyTypeHandler, it will start MyTypeHandler. Sometimes the typeHandler can be explicitly enabled. Generally speaking, there are two ways to enable this typeHandler, as shown below.

....
<resultMap id="roleMapper" type="role">
    <result property="id" column="id"/>
    <result property="roleName" column="role_name" jdbcType="VARCHAR" javaType="string"/>
    <result property="note" column="note" typeHandler=" com.mybatis.test.MyTypeHandler"/>
</resultMap>

<select id="getRole" parameterType="long" resultMap="roleMapper">
    select id,role_name,note from t_role where id = #{id}
</select>

<select id="findRoles" parameterType="string" resultMap="roleMapper">
    select id, role_name, note from t_role
    where role_name like concat('%',#{roleName, jdbcType=VARCHAR,
    javaType=string}, '%')
</select>
<select id="findRoles2" parameterType="string" resultMap="roleMapper">
    select id, role_name, note from t_role
    where note like concat ('%', # {note, typeHandler=com.mybatis.test.MyTypeHandler},'%')
</select>
......

Note that either jdbcType and javaType consistent with the custom typeHandler are specified, or the specific implementation class is specified directly using typeHandler.

In some situations where it is impossible to determine which typeHandler to use for processing because the database returns empty, and the corresponding javaType typeHandler is not registered, MyBatis cannot know which typeHandler to use to convert data. We can use this method to determine which typeHandler to use for processing, so There will be no exceptions.

Sometimes because there are many types of enumerations, the system needs a lot of typeHandlers, and it will be troublesome to configure them. At this time, you can consider using the form of package scanning, then you need to configure them according to the following code.

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

It's just that you can't specify jdbcType and javaType, but we can use annotations to handle them. Let's modify the declaration of MyTypeHandler as follows.

@MappedTypes(String.class)
@MappedjdbcTypes(jdbcType.VARCHAR)
public class MyTypeHandler implements TypeHandler<String>{
    ......
}

Guess you like

Origin blog.csdn.net/unbelievevc/article/details/132311210