TypeHandler

157 阅读2分钟

以下是 MyBatis 中 内置的 JDBC 类型与 Java 类型的默认映射关系,涵盖所有官方支持的 TypeHandler


一、MyBatis 内置的 TypeHandler 映射表

JDBC 类型Java 类型说明
ARRAYjava.sql.Array数据库数组类型 → Java Array 对象
BITBoolean数据库的 BIT 类型 → Java Boolean
TINYINTInteger1字节整数 → Java Integer
SMALLINTInteger2字节整数 → Java Integer
INTEGERInteger4字节整数 → Java Integer
BIGINTLong8字节整数 → Java Long
FLOATFloat单精度浮点数 → Java Float
REALFloatFLOAT
DOUBLEDouble双精度浮点数 → Java Double
DECIMALBigDecimal高精度小数 → Java BigDecimal
NUMERICBigDecimalDECIMAL
CHARString定长字符串 → Java String
VARCHARString变长字符串 → Java String
LONGVARCHARString长文本 → Java String
NCHARStringUnicode 定长字符串 → Java String
NVARCHARStringUnicode 变长字符串 → Java String
LONGNVARCHARStringUnicode 长文本 → Java String
BOOLEANBoolean布尔值 → Java Boolean
DATEjava.util.Date java.sql.Date日期 → java.util.Datejava.sql.Date(取决于配置)
TIMEjava.sql.Time时间 → java.sql.Time
TIMESTAMPjava.sql.Timestamp时间戳 → java.sql.Timestamp
CLOBjava.sql.Clob大文本 → Clob 对象
BLOBbyte[] java.sql.Blob二进制数据 → 字节数组或 Blob 对象(取决于配置)
BINARYbyte[]定长二进制 → 字节数组
VARBINARYbyte[]变长二进制 → 字节数组
LONGVARBINARYbyte[]长二进制 → 字节数组
NULLnull数据库 NULL → Java null
OTHERObject未明确定义的类型 → Java Object
CURSORResultSet数据库游标 → ResultSet(用于存储过程)

二、特殊类型映射

1. 枚举类型

  • 默认行为:MyBatis 默认将枚举的 name() 存储为 VARCHAR 类型。

  • 自定义映射:若需存储枚举的 ordinal()(序号)或其他字段,需实现 TypeHandler

    // 示例:将枚举存储为序号
    public class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
        private final Class<E> type;
        public EnumOrdinalTypeHandler(Class<E> type) {
            this.type = type;
        }
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) {
            ps.setInt(i, parameter.ordinal());
        }
        // 其他方法实现(略)
    }
    

2. 集合类型

  • List/Array:通过 <foreach> 标签动态生成 IN 查询。

    <select id="selectUsersByIds" resultType="User">
        SELECT * FROM user WHERE id IN
        <foreach item="id" collection="ids" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>
    

三、隐式类型转换

MyBatis 支持以下 隐式类型转换(无需配置):

Java 类型可转换的 JDBC 类型
StringCHAR, VARCHAR, LONGVARCHAR, CLOB
IntegerINTEGER, SMALLINT, TINYINT
LongBIGINT
DoubleDOUBLE, FLOAT
BigDecimalDECIMAL, NUMERIC
BooleanBIT, BOOLEAN

四、自定义类型映射

1. 实现 TypeHandler 接口

public class JsonTypeHandler<T> extends BaseTypeHandler<T> {
    private final Class<T> type;
    public JsonTypeHandler(Class<T> type) {
        this.type = type;
    }
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) {
        ps.setString(i, JSON.toJSONString(parameter));
    }
    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return JSON.parseObject(rs.getString(columnName), type);
    }
    // 其他方法实现(略)
}

2. 注册自定义 TypeHandler

  • 全局注册mybatis-config.xml):

    <typeHandlers>
        <typeHandler handler="com.example.JsonTypeHandler" javaType="com.example.DataModel"/>
    </typeHandlers>
    
  • 局部指定(Mapper XML):

    <resultMap id="dataMap" type="DataModel">
        <result property="metadata" column="metadata" typeHandler="com.example.JsonTypeHandler"/>
    </resultMap>
    

五、总结

  1. 默认覆盖范围:MyBatis 内置了所有基础类型和常见 JDBC 类型的映射。

  2. 隐式转换:支持数值、字符串等类型的自动转换。

  3. 扩展性:通过自定义 TypeHandler 可处理复杂类型(如枚举、JSON、自定义对象)。

  4. 常见问题

    • 类型不匹配:检查 jdbcTypejavaType 是否正确定义。
    • 枚举存储:默认存储 name(),需自定义实现存储序号或其他字段。

完整官方文档参考MyBatis TypeHandlers