Implementation of Mybatis-TypeHandler Based on SpringBook Customization

Demand:
Enumerations are used in programs to represent states or options, while numbers are used in databases to store them. The advantage of doing this is that enum is used in the program more intuitively to know the state and meaning of each value.

Analysis:
EnumTypeHandler and EnumOrdinal TypeHandler are two existing types of TypeHandler

The difference between the two:
EnumTypeHandler stores the name of the enumeration in the database, and EnumOrdinalTypeHandler stores the location of the enumeration in the database.

Example:

public enum  sexEnum implements DemoEnum {

   WOMAN(0),MAN(1);
   private int code;
   private sexEnum(int code){
       this.code =code;
   }
    @Override
    public int getValue() {
        return code;
    }
}

The EnumTypeHandler transformation retrieves WOMAN OR MAN

EnumOrdinalTypeHandler gets 0 OR 1 (not the number in WOMAN() in the gender enumeration in our code above, but the location)

Because we need to customize a TypeHandler:

Don't talk much about code directly:

1. Define an interface to convert values from a database

public interface DemoEnum {
    int getValue();
}

2. Customize a public class based on BaseTypeHandler to decouple when you have multiple enumerated classes. The get method is the function of the interface defined in the previous step:

public class testTypeHandler<E extends Enum<E> & DemoEnum> extends BaseTypeHandler<E> {

    private Class<E> type;
    private final E[] enums;
    public testTypeHandler(Class<E> 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.");
        }
    }

    public E get(int code) {
        try {
            for(E e:enums) {
                if(e.getValue() == code) {
                    return e;
                }
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("erro value!");
        }
        return null;
    }
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i,parameter.getValue());
    }
    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        int value = rs.getInt(columnName);
        if (rs.wasNull()) {
            return null;
        }else {
            return get(value);
        }
    }
    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int value = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        }else {
            return get(value);
        }

    }
    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        int value = cs.getInt(columnIndex);
        if (cs.wasNull()) {
            return null;
        }else {
            return get(value);
        }

    }


}

3. Create a new public class based on the base class in the previous step. If you have multiple enumeration attributes that need to be converted, you can add your enumeration class to the Mapped Types annotation so that you don't need to implement a TypeHandler at a time:

@MappedTypes({sexEnum.class})
public class EnumTypeHandler<E extends Enum<E> & DemoEnum> extends testTypeHandler<E> {
    public EnumTypeHandler(Class<E> type) {
        super(type);
    }
}

4. Configuration in application.properties

mybatis.type-handlers-package = the package path of your public class

 

 

Summary: Writing may be a bit rough, I hope to communicate with you.

Keywords: Database Mybatis

Added by chomps on Sun, 12 May 2019 14:34:08 +0300