mybatis custom enumeration conversion class

EnumTypeHandler is the default enumeration type converter of mybatis. If an enumeration type is used in the pojo class and the configuration file does not specify a type conversion class, mybatis will use EnumTypeHandler to process the enumeration properties. EnumTypeHandler will store the name of the enumeration class, and the name of the enumeration class is the name of the enumeration class.

EnumOrdinalTypeHandler is another converter provided by mybatis. As the name suggests, this conversion class uses the ordinal attribute of the enumeration class as database storage information. Since the ordinal attribute is of type int, according to the official website, the corresponding resource in the database should be of type int or double Yes, but MYSQL varchar fields can also be stored during personal testing.

Summary: The difference between EnumTypeHandler and EnumOrdinalTypeHandler is mainly the difference in the type of fields stored in the database. Since EnumOrdinalTypeHandler uses ordinal of enumeration type as storage, it must use numeric type field storage.

There might be a need: for some reason, we don't want to use the enum's name and ordinal as data storage fields. Mybatis' custom transformation class appeared.

Preconditions

1. Mybatis abandoned the TypeHandlerCallback interface of ibatis, and replaced it with TypeHandler, which is slightly different from the original interface, but the method is similar. (see instructions https://code.google.com/p/mybatis/wiki/DocUpgrade3)

2. BaseTypeHandler is the basic conversion class provided by mybatis. This class implements the TypeHandler interface and provides many public methods. It is recommended that each custom conversion class inherit it.

Example

    Use a piece of code to store the code attribute in the enumeration class EnumStatus to the corresponding field statusCustom in the database.

enum class

package com.sg.bean;

public enum EnumStatus {
    NORMAL(1, "normal"),
    DELETE(0, "Delete"),
    CANCEL(2, "Logout");
    private EnumStatus(int code, String description) {
        this.code = new Integer(code);
        this.description = description;
    }
    private Integer code;
    private String description;
    public Integer getCode() {
    
        return code;
    }
    public String getDescription() {
    
        return description;
    }
}

custom conversion class
package com.sg.util.typehandler;

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

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import com.sg.bean.EnumStatus;

/**
 * Custom EnumStatus conversion class<br>
 * Storage property: EnumStatus.getCode() <br>
 * JDBCType:INT
 * @author yanlei
 */
public class EnumStatusHandler extends BaseTypeHandler<EnumStatus> {

    private Class<EnumStatus> type;

    private final EnumStatus[] enums;

    /**
     * Set the conversion class and enumeration class content set by the configuration file for more convenient and efficient implementation of other methods
     * @param type The conversion class set in the configuration file
     */
    public EnumStatusHandler(Class<EnumStatus> type) {
        if (type == null)
            throw new IllegalArgumentException("Type argument cannot be null");
        this.type = type;
        this.enums = type.getEnumConstants();
        if (this.enums == null)
            throw new IllegalArgumentException(type.getSimpleName()
                    + " does not represent an enum type.");
    }

    @Override
    public EnumStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // Determine the acquisition type according to the database storage type. In this example, the database stores the INT type
        int i = rs.getInt(columnName);
        
        if (rs.wasNull()) {
            return null;
        } else {
            // According to the code value in the database, locate the EnumStatus subclass
            return locateEnumStatus(i);
        }
    }

    @Override
    public EnumStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // Determine the acquisition type according to the database storage type. In this example, the database stores the INT type
        int i = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            // According to the code value in the database, locate the EnumStatus subclass
            return locateEnumStatus(i);
        }
    }

    @Override
    public EnumStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // Determine the acquisition type according to the database storage type. In this example, the database stores the INT type
        int i = cs.getInt(columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            // According to the code value in the database, locate the EnumStatus subclass
            return locateEnumStatus(i);
        }
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, EnumStatus parameter, JdbcType jdbcType)
            throws SQLException {
        // baseTypeHandler has helped us to do the null judgment of the parameter
        ps.setInt(i, parameter.getCode());

    }
    
    /**
     * Enumeration type conversion, because the constructor obtains the subclass enums of the enumeration, making the traversal more efficient and faster
     * @param code The custom code attribute stored in the database
     * @return code corresponding to the enumeration class
     */
    private EnumStatus locateEnumStatus(int code) {
        for(EnumStatus status : enums) {
            if(status.getCode().equals(Integer.valueOf(code))) {
                return status;
            }
        }
        throw new IllegalArgumentException("Unknown enumeration type: " + code + ", please check " + type.getSimpleName());
    }

}

entity class

package com.sg.bean;


public class User {

    private String id;
    
    private String accountID;
    
    private String userName;
    
    private EnumStatus statusDef; //enumerate properties, use mybatis default conversion class
    
    private EnumStatus statusOrdinal; //Enumerate properties, use EnumOrdinalTypeHandler to convert
    
    private EnumStatus statusCustom; // Enumeration properties, custom enumeration conversion class
    
    public String getId() {
        return id;
    }

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

    
    public String getAccountID() {
        return accountID;
    }

    
    public void setAccountID(String accountID) {
        this.accountID = accountID;
    }

    
    public String getUserName() {
        return userName;
    }

    
    public void setUserName(String userName) {
        this.userName = userName;
    }

    
    public EnumStatus getStatusDef() {
        return statusDef;
    }

    public void setStatusDef(EnumStatus statusDef) {
        this.statusDef = statusDef;
    }

    public EnumStatus getStatusOrdinal() {
        return statusOrdinal;
    }

    public void setStatusOrdinal(EnumStatus statusOrdinal) {
        this.statusOrdinal = statusOrdinal;
    }
    
    public EnumStatus getStatusCustom() {
        return statusCustom;
    }

    public void setStatusCustom(EnumStatus statusCustom) {
        this.statusCustom = statusCustom;
    }
    
    @Override
    public String toString() {
        StringBuffer str = new StringBuffer();
        str.append("id:");
        str.append(id);
        str.append("\n");
        
        str.append("userName:");
        str.append(userName);
        str.append("\n");
        
        str.append("statusDef:");
        str.append(statusDef.name());
        str.append("\n");
        
        str.append("statusOrdinal:");
        str.append(statusOrdinal.name());
        str.append("\n");
        str.append("statusCustom:");
        str.append(statusCustom.name());
        str.append("\n");
        return str.toString();
    }
}

mybatis configuration 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.sg.bean.User">

  <resultMap type="User" id="userMap">
	<id column="id" property="id"/>
	<result column="accountID" property="accountID"/>
	<result column="userName" property="userName"/>
	<result column="statusDef" property="statusDef"/>
	<result column="statusOrdinal" property="statusOrdinal" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
	<result column="statusCustom" property="statusCustom" typeHandler="com.sg.util.typehandler.EnumStatusHandler"/>
  </resultMap>
  
  <select id="selectUser" resultMap="userMap">
    select * from t_user where id = #{id}
  </select>
  
  <insert id="insertUser" parameterType="User">
  	insert into t_user(id,accountID,userName,statusDef,statusOrdinal,statusCustom)
  	values(
  	#{id}, #{accountID}, #{userName},
  	#{statusDef},
  	#{statusOrdinal, typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},
  	#{statusCustom, typeHandler=com.sg.util.typehandler.EnumStatusHandler}
  	)
  </insert>
</mapper>

database script

CREATE TABLE `t_user` (
  `id` varchar(45) NOT NULL,
  `accountID` varchar(45) DEFAULT NULL,
  `userName` varchar(45) DEFAULT NULL,
  `statusDef` varchar(45) DEFAULT NULL,
  `statusOrdinal` varchar(45) DEFAULT NULL,
  `statusCustom` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='User table';


Reprinted from: https://my.oschina.net/SEyanlei/blog/188919

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325415508&siteId=291194637