Type processor for Mybatis

Posted by saco721 on Sat, 07 Dec 2019 09:33:27 +0100

When Mybatis sets a parameter in the prepared statement, it uses the default typeHandler for processing.

When you want to search a person's information by name

<select id="getRole" parameterType="string" resultRole="role">
    select rolename,phonenumber from t_role where rolename = #{rolname}
</select>

When Mybatis calls this query statement, it will become a preprocessing statement

select rolename,phonenumber from t_role where rolename = ?

This one That is, what value should be filled in the placeholder?

At this time, because rolename is of String type, rolename will go to StringTypeHandler, the processor that Mybatis has implemented

public class StringTypeHandler implements TypeHandler<String> {

    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter);
    }

    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getString(columnName);
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getString(columnIndex);
    }

    @Override
    public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getString(columnIndex);
    }
}

We just need to look at the first method now. rolename will know when he sees this method. This' The placeholder should have filled in myself.

The result set is the same as the stored procedure.

If Mybatis can't find a converter of type, it doesn't know what to do, like the following code

<insert id="addPerson" parameterType="person">
    insert into people(id, name, phonenumber)
    values(#{id}, #{name},#{phonenumber})
</insert>

phonenumber is a class created by ourselves. It looks like this:

private String countryCode;
    private String stateCode;
    private String number;
    public PhoneNumber() {
    }
    // 021-3359-3216
    public PhoneNumber(String str) {
        String[] number = str.split("[-]");
        this.countryCode = number[0];
        this.stateCode = number[1];
        this.number = number[2];
    }
    // 021,3359,3216
    public PhoneNumber(String countryCode, String stateCode, String number) {
        this.countryCode = countryCode;
        this.stateCode = stateCode;
        this.number = number;
    }
    public String getAsString() {
        return countryCode + "-" + stateCode + "-" + number;
    }
    public String getCountryCode() {
        return countryCode;
    }
    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }
    public String getStateCode() {
        return stateCode;
    }
    public void setStateCode(String stateCode) {
        this.stateCode = stateCode;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }

So we need to tell Mybatis what to fill in the preprocessing statement placeholder, and then we need to redefine a typeHandler ourselves

public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber> {
    //How to set the value in ps when encountering the PhoneNumber parameter
    //ps.setXXX()
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, PhoneNumber parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setString(i, parameter.getAsString());
    }
    //How to encapsulate the PhoneNumber type encountered in the query (using column name encapsulation)
    //stuedent.setTelPhone(new PhoneNumber("021-3359-3216"))
    @Override
    public PhoneNumber getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return new PhoneNumber(rs.getString(columnName));
    }
    //How to encapsulate the PhoneNumber type encountered in the query (using the column's subscript)
    @Override
    public PhoneNumber getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return new PhoneNumber(rs.getString(columnIndex));
    }
    //How to encapsulate the PhoneNumber type when using the CallableStatement
    @Override
    public PhoneNumber getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return new PhoneNumber(cs.getString(columnIndex));
    }
}

Topics: Java Mybatis Stored Procedure