SoFunction
Updated on 2025-04-12

The role and description of the TypeHandler of MyBatis type processor

TypeHandlerIt is the interface in MyBatis for processing conversion between Java types and JDBC types. It plays a crucial role in the parameter binding and result mapping of MyBatis.

Why do I need a TypeHandler?

Java and databases (JDBC) use different type systems. For example:

  • There is in JavaStringIntegerDateBooleanenumetc.
  • There are in JDBCVARCHARINTEGERDATEBOOLEANTIMESTAMPBLOBetc.

When MyBatis executes SQL statements, it is necessary to set the data in the Java object to the JDBC'sPreparedStatement(parameter binding), and JDBC'sResultSetThe data in it is converted to a Java object (result map).TypeHandlerIt is responsible for handling type conversion in both cases.

The role of TypeHandler

Parameter binding (Java type -> JDBC type):

  • When MyBatis sets the data in a Java object toPreparedStatementplaceholder (#{})hour,TypeHandlerThe Java type will be converted to the corresponding JDBC type.
  • For example, to use JavaStringType conversion to JDBCVARCHARType, Java'sDateType conversion to JDBCTIMESTAMPtype.

Result Map (JDBC Type -> Java Type):

  • When MyBatis fromResultSetWhen reading data and mapping it into a Java object,TypeHandlerThe JDBC type will be converted to the corresponding Java type.
  • For example, to JDBC'sVARCHARType conversion to JavaStringType, will JDBCINTEGERType conversion to JavaIntegertype.

TypeHandler interface definition

public interface TypeHandler<T> {

  // Parameter binding: Convert Java type to JDBC type and set it to PreparedStatement  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  // Result Map: Get the data of the specified column from the ResultSet and convert it to Java type  T getResult(ResultSet rs, String columnName) throws SQLException;

  // Result Mapping: Get the data of the specified column index from the ResultSet and convert it to Java type  T getResult(ResultSet rs, int columnIndex) throws SQLException;
  
    // Result map: Get the data of the specified column index from CallableStatement and convert it to java type  T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}
  • setParameter(): Set Java type parametersparameterSet toPreparedStatementThe firstiplaceholders and specify JDBC typejdbcTypejdbcTypeCan be empty, MyBatis will try to automatically infer).
  • getResult(): There are three overloaded methods, respectively, based on the column name and column indexResultSetget data fromCallableStatementGets the data and converts it to Java type.

MyBatis built-in TypeHandler

MyBatis has many commonly used ones built inTypeHandler, used to handle common type conversions. For example:

  • StringTypeHandler: deal withStringtype.
  • IntegerTypeHandler: deal withIntegertype.
  • LongTypeHandler: deal withLongtype.
  • DateTypeHandler: deal withtype.
  • BooleanTypeHandler: deal withBooleantype.
  • EnumTypeHandler: Process the enum type (the name of the enum is used by default).
  • EnumOrdinalTypeHandler: Process the enum type (using ordinal numbers of enums).
  • BlobTypeHandler: Processing binary large objects (BLOBs).
  • ClobTypeHandler: Process large characters (CLOB).
  • SqlDateTypeHandler:deal withtype
  • SqlTimeTypeHandler:deal withtype
  • SqlTimestampTypeHandler:deal withtype

Custom TypeHandler

When MyBatis is built-inTypeHandlerWhen the requirements cannot be met, we can customize themTypeHandler. For example:

  • Handle special types:For example, convert a JSON string in a database to a Java object, or convert a Java object to a JSON string to store it in the database.
  • Custom type conversion logic:For example, make special formatting of date types, or use custom conversion rules for enum types.

Steps to customize TypeHandler

1. ImplementationTypeHandler interface:Create a class to implementTypeHandlerinterface and implement methods in the interface.

2. Register TypeHandler:There are two ways to register custom onesTypeHandler

  • XML configuration:existIn the file, use<typeHandlers>Tag registrationTypeHandler
<typeHandlers>
  <typeHandler handler="" javaType="" jdbcType="VARCHAR"/>
</typeHandlers>
  • Or use package scanning:
 <typeHandlers>
     <package name=""/>
 </typeHandlers>
  • Annotation configuration:In customTypeHandlerUsed on the class@MappedTypesand@MappedJdbcTypesannotation.
@MappedTypes() // Specify Java type@MappedJdbcTypes() // Specify the JDBC typepublic class MyTypeHandler implements TypeHandler&lt;MyType&gt; {
    // ... Methods to implement TypeHandler interface ...}

3. Specify jdbcType (optional):If MyBatis cannot infer, it must passjdbcTypeThe attribute isnullValue specifies the type of database column

  • Example:
  • Customize a TypeHandler that converts the VARCHAR type in the database to an enum type in Java:
// Suppose there is an enumeration typepublic enum Status {
    ACTIVE, INACTIVE, PENDING
}

// Custom TypeHandler@MappedTypes()
@MappedJdbcTypes()
public class StatusTypeHandler implements TypeHandler&lt;Status&gt; {

    @Override
    public void setParameter(PreparedStatement ps, int i, Status parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) {
            (i, null);
        } else {
            (i, ()); //Storing the enum name to the database        }
    }

    @Override
    public Status getResult(ResultSet rs, String columnName) throws SQLException {
        String value = (columnName);
        return getStatus(value);
    }

    @Override
    public Status getResult(ResultSet rs, int columnIndex) throws SQLException {
        String value = (columnIndex);
         return getStatus(value);
    }

    @Override
    public Status getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = (columnIndex);
        return getStatus(value);
    }
    
    private Status getStatus(String value){
         if (value == null) {
            return null;
        }
        try {
            return (value); // Get enum value from database according to name        } catch (IllegalArgumentException e) {
            return null; // Or throw an exception        }
    }
}

// Register TypeHandler in&lt;typeHandlers&gt;
  &lt;typeHandler handler=""/&gt;
&lt;/typeHandlers&gt;

// Or use it in a Mapper XML file&lt;resultMap  type="User"&gt;
    &lt;result property="status" column="status" javaType="" jdbcType="VARCHAR" typeHandler=""/&gt;
&lt;/resultMap&gt;

Summarize

TypeHandlerIt is a key component in MyBatis for handling conversion between Java types and JDBC types.

MyBatis has many commonly used ones built inTypeHandler, in most cases we can directly use the built-inTypeHandler

When it is necessary to deal with special types or custom type conversion logic, we can customizeTypeHandler, and register customTypeHandler

The above is personal experience. I hope you can give you a reference and I hope you can support me more.