java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatis类型处理器TypeHandler作用

MyBatis类型处理器TypeHandler的作用及说明

作者:冰糖心书房

这篇文章主要介绍了MyBatis类型处理器TypeHandler的作用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

TypeHandler 是 MyBatis 中用于处理 Java 类型与 JDBC 类型之间转换的接口。它在 MyBatis 的参数绑定和结果映射过程中起着至关重要的作用。

为什么需要 TypeHandler?

Java 和 数据库(JDBC)使用不同的类型系统。例如:

当 MyBatis 执行 SQL 语句时,需要将 Java 对象中的数据设置到 JDBC 的 PreparedStatement 中(参数绑定),以及将 JDBC 的 ResultSet 中的数据转换为 Java 对象(结果映射)。TypeHandler 就负责处理这两种情况下的类型转换。

TypeHandler 的作用

参数绑定 (Java 类型 -> JDBC 类型):

结果映射 (JDBC 类型 -> Java 类型):

TypeHandler 的接口定义

public interface TypeHandler<T> {

  // 参数绑定:将 Java 类型转换为 JDBC 类型,并设置到 PreparedStatement 中
  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  // 结果映射:从 ResultSet 中获取指定列的数据,并将其转换为 Java 类型
  T getResult(ResultSet rs, String columnName) throws SQLException;

  // 结果映射:从 ResultSet 中获取指定列索引的数据,并将其转换为 Java 类型
  T getResult(ResultSet rs, int columnIndex) throws SQLException;
  
    // 结果映射:从 CallableStatement 中获取指定列索引的数据,将其转换为java类型
  T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}

MyBatis 内置的 TypeHandler

MyBatis 内置了许多常用的 TypeHandler,用于处理常见的类型转换。例如:

自定义 TypeHandler

当 MyBatis 内置的 TypeHandler 不能满足需求时,我们可以自定义 TypeHandler。例如:

自定义 TypeHandler 的步骤

1.实现 TypeHandler 接口: 创建一个类,实现 TypeHandler 接口,并实现接口中的方法。

2.注册 TypeHandler: 有两种方式注册自定义的 TypeHandler

<typeHandlers>
  <typeHandler handler="com.example.MyTypeHandler" javaType="com.example.MyType" jdbcType="VARCHAR"/>
</typeHandlers>
 <typeHandlers>
     <package name="com.example.typehandler"/>
 </typeHandlers>
@MappedTypes(MyType.class) // 指定 Java 类型
@MappedJdbcTypes(JdbcType.VARCHAR) // 指定 JDBC 类型
public class MyTypeHandler implements TypeHandler<MyType> {
    // ... 实现 TypeHandler 接口的方法 ...
}

3.指定jdbcType(可选): 如果MyBatis无法推断,则必须通过jdbcType属性为null值指定数据库列的类型

// 假设有一个枚举类型
public enum Status {
    ACTIVE, INACTIVE, PENDING
}

// 自定义 TypeHandler
@MappedTypes(Status.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class StatusTypeHandler implements TypeHandler<Status> {

    @Override
    public void setParameter(PreparedStatement ps, int i, Status parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) {
            ps.setString(i, null);
        } else {
            ps.setString(i, parameter.name()); // 将枚举的名称存储到数据库
        }
    }

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

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

    @Override
    public Status getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = cs.getString(columnIndex);
        return getStatus(value);
    }
    
    private Status getStatus(String value){
         if (value == null) {
            return null;
        }
        try {
            return Status.valueOf(value); // 根据名称从数据库中获取枚举值
        } catch (IllegalArgumentException e) {
            return null; // 或者抛出异常
        }
    }
}

// 在 mybatis-config.xml 中注册 TypeHandler
<typeHandlers>
  <typeHandler handler="com.example.StatusTypeHandler"/>
</typeHandlers>

// 或者在 Mapper XML 文件中使用
<resultMap id="userResultMap" type="User">
    <result property="status" column="status" javaType="com.example.Status" jdbcType="VARCHAR" typeHandler="com.example.StatusTypeHandler"/>
</resultMap>

总结

TypeHandler 是 MyBatis 中用于处理 Java 类型与 JDBC 类型之间转换的关键组件。

MyBatis 内置了许多常用的 TypeHandler,在大多数情况下,我们可以直接使用内置的 TypeHandler

当需要处理特殊类型或自定义类型转换逻辑时,我们可以自定义 TypeHandler,并通过 XML 配置或注解的方式注册自定义的 TypeHandler

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文