The custom TypeHandler in Mybatis handles an exception handling of enumeration classes

In mybatis, we can customize the parameter encapsulation policy when setting parameters or fetching the result set in the form of custom TypeHandler. For example, if the status code of an employee is 100, we display the status code 100 in the status code column empStatus in the database, but when querying the employee in the database through mybatis, we want to display his status column as the current status of the employee. For example, the status code 100 corresponds to the status of LOGIN, logo, remove, etc. After that, you can use TypeHandler to customize the parameter encapsulation of query results.

Using TypeHandler to customize the encapsulation result set needs to write the class of encapsulation rules. This class needs to implement the TypeHandler interface and write the methods from the four interfaces.

public interface TypeHandler<T> {
  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
  T getResult(ResultSet rs, String columnName) throws SQLException;
  T getResult(ResultSet rs, int columnIndex) throws SQLException;
  T getResult(CallableStatement cs, int columnIndex) throws SQLException;

}

First, you need to write an enumeration class EmpStatus representing employee status

public enum EmpStatus {
    LOGIN(100, "User incumbency"), LOGOUT(200, "User out"), REMOVE(300, "user does not exist");

    private Integer code;
    private String msg;

    private EmpStatus(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    //Returns the enumeration class object according to the status code
    public static EmpStatus getEmpStatusByCode(Integer code) {
        switch (code) {
            case 100:
                return LOGIN;
            case 200:
                return LOGOUT;
            case 300:
                return REMOVE;
            default:
                return LOGOUT;
        }
    }
}

Then write the implementation class MyEnumEmpStatusTypeHandler of TypeHandler

public class MyEnumEmpStatusTypeHandler implements TypeHandler<EmpStatus> {


    /**
     * Defines how the current data is saved into the database
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setParameter(PreparedStatement ps, int i, EmpStatus parameter, JdbcType jdbcType) throws SQLException {
        System.out.println("Status code to save:" + parameter.getCode());
        ps.setString(i,parameter.getCode().toString());
    }

    @Override
    public EmpStatus getResult(ResultSet rs, String columnName) throws SQLException {
//        An enumeration object is returned according to the status code of the enumeration class obtained from the database
        int code = rs.getInt(columnName);
        System.out.println("Status code obtained from database:" + code);
        EmpStatus status = EmpStatus.getEmpStatusByCode(code);
        return status;
    }

    @Override
    public EmpStatus getResult(ResultSet rs, int columnIndex) throws SQLException {
//        An enumeration object is returned according to the status code of the enumeration class obtained from the database
        int code = rs.getInt(columnIndex);
        System.out.println("Status code obtained from database:" + code);
        EmpStatus status = EmpStatus.getEmpStatusByCode(code);
        return status;
    }

    @Override
    public EmpStatus getResult(CallableStatement cs, int columnIndex) throws SQLException {
//      An enumeration object is returned according to the status code of the enumeration class obtained from the database
        int code = cs.getInt(columnIndex);
        System.out.println("Status code obtained from database:" + code);
        EmpStatus status = EmpStatus.getEmpStatusByCode(code);
        return status;
    }
}

Next, configure the encapsulation rules of the custom TypeHandler in the global configuration file of mybatis

<typeHandlers>
        <typeHandler handler="MyEnumEmpStatusTypeHandler Class full path"
                     javaType="Enumeration class full path"/>
    </typeHandlers>

Employee information in mysql

It is worth noting here that the column name of the Employee status column empstatus in mysql must be the same as the name of the enumeration class empstatus and the status object empstatus defined in Employee. mysql is not case sensitive, so it doesn't matter if the letters are inconsistent in case.

  private EmpStatus empstatus = EmpStatus.LOGOUT;

If the two names are different, I set the column name to employee in mysql at the beginning_ Status. In the later test, no matter whether I change the status code of the employee in mysql to 100200 or 300, the result obtained by querying getEmpstatus() is LOGOUT, and the output item set in MyEnumEmpStatusTypeHandler is system out. None of the values in println () are output, indicating that the user-defined TypeHandler is not called, but the default value I set in the Employee class private empstatus empstatus = empstatus LOGOUT this attribute. The custom TypeHandler doesn't work at all.

 try {
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Employee employee = mapper.getEmployeeById(17);
            System.out.println(employee.getEmpstatus());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            openSession.close();
        }

DEBUG 07-31 14:41:08,025 ==>  Preparing: select id,last_name lastName,gender,email,employee_status from tbl_employee where id = ?   (BaseJdbcLogger.java:145) 
DEBUG 07-31 14:41:08,056 ==> Parameters: 18(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 07-31 14:41:08,072 <==      Total: 1  (BaseJdbcLogger.java:145) 
LOGOUT

Later, the employee status column name in mysql will be changed from employee to employee_ After the status is changed to empStatus, the query is normal, and the overridden methods in the TypeHandler implementation class are also called. Exception resolved. Of course, if hump naming is enabled here, the column name may be set to emp_Status should be OK, but I didn't try.

DEBUG 07-31 14:35:02,821 ==>  Preparing: select id,last_name lastName,gender,email,empStatus from tbl_employee where id = ?   (BaseJdbcLogger.java:145) 
DEBUG 07-31 14:35:02,852 ==> Parameters: 18(Integer)  (BaseJdbcLogger.java:145) 
Status code obtained from database: 300
DEBUG 07-31 14:35:02,868 <==      Total: 1  (BaseJdbcLogger.java:145) 
REMOVE

Keywords: Mybatis

Added by sunnysideup on Sun, 02 Jan 2022 08:43:10 +0200