TypeHandler
It 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 Java
String
、Integer
、Date
、Boolean
、enum
etc. - There are in JDBC
VARCHAR
、INTEGER
、DATE
、BOOLEAN
、TIMESTAMP
、BLOB
etc.
When MyBatis executes SQL statements, it is necessary to set the data in the Java object to the JDBC'sPreparedStatement
(parameter binding), and JDBC'sResultSet
The data in it is converted to a Java object (result map).TypeHandler
It 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 to
PreparedStatement
placeholder (#{}
)hour,TypeHandler
The Java type will be converted to the corresponding JDBC type. - For example, to use Java
String
Type conversion to JDBCVARCHAR
Type, Java'sDate
Type conversion to JDBCTIMESTAMP
type.
Result Map (JDBC Type -> Java Type):
- When MyBatis from
ResultSet
When reading data and mapping it into a Java object,TypeHandler
The JDBC type will be converted to the corresponding Java type. - For example, to JDBC's
VARCHAR
Type conversion to JavaString
Type, will JDBCINTEGER
Type conversion to JavaInteger
type.
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 parametersparameter
Set toPreparedStatement
The firsti
placeholders and specify JDBC typejdbcType
(jdbcType
Can be empty, MyBatis will try to automatically infer). -
getResult()
: There are three overloaded methods, respectively, based on the column name and column indexResultSet
get data fromCallableStatement
Gets 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 withString
type. -
IntegerTypeHandler
: deal withInteger
type. -
LongTypeHandler
: deal withLong
type. -
DateTypeHandler
: deal withtype.
-
BooleanTypeHandler
: deal withBoolean
type. -
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-inTypeHandler
When 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 implementTypeHandler
interface and implement methods in the interface.
2. Register TypeHandler:There are two ways to register custom onesTypeHandler
:
-
XML configuration:exist
In the file, use
<typeHandlers>
Tag registrationTypeHandler
。
<typeHandlers> <typeHandler handler="" javaType="" jdbcType="VARCHAR"/> </typeHandlers>
- Or use package scanning:
<typeHandlers> <package name=""/> </typeHandlers>
-
Annotation configuration:In custom
TypeHandler
Used on the class@MappedTypes
and@MappedJdbcTypes
annotation.
@MappedTypes() // Specify Java type@MappedJdbcTypes() // Specify the JDBC typepublic class MyTypeHandler implements TypeHandler<MyType> { // ... Methods to implement TypeHandler interface ...}
3. Specify jdbcType (optional):If MyBatis cannot infer, it must passjdbcType
The attribute isnull
Value 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<Status> { @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<typeHandlers> <typeHandler handler=""/> </typeHandlers> // Or use it in a Mapper XML file<resultMap type="User"> <result property="status" column="status" javaType="" jdbcType="VARCHAR" typeHandler=""/> </resultMap>
Summarize
TypeHandler
It 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.