Mybatis类型转换器使用

本文介绍了MyBatis中如何自定义类型转换器,以处理Java对象与数据库中JSON字符串的转换。通过创建一个继承自BaseTypeHandler的MyTypeHandler,实现了将UserVO对象转换为JSON字符串存储到数据库,以及从数据库读取JSON字符串并转换回UserVO对象的过程。在实际应用中,当需要对复杂类型进行映射时,这种自定义类型转换器十分有用。

1、mybatis类型转换器,就是Java类型与数据库的类型之间转换的一个中介,由这个转换器可以对类型进行映射,mybatis对于基础类型都有默认类型转换器,你可以自定义类型转换器替代默认的转换器,大多数情况下你无需替代它,但是对于Java中的复杂类型,比如对象想要映射成数据库的json字符串,那么你就可以自定义类型转换器。
mybatis自定义类型转换器可以继承TypeHandlerBaseTypeHandler两个接口,并实现其中的方法。
BaseTypeHandler继承TypeHandler,它们之间的关系使用了设计模式模板方法

2、下面就以Java中为对象,数据库中为JSON串相互转换作为例子,来对类型转换器进行一个简单的学习。

2.1 数据库有用户表,用户表中每个用户有自己的账号account,account作为JSON串存储。
在这里插入图片描述
2.2 在Java中我们定义一个UserVO对象,其中account为一个对象,其他字段都是基础数据类型:
在这里插入图片描述
2.3 编写自定义类型转换器,实现Java Accound对象 <---->数据库account字符串 相互转换,即新增时 Java Account Object --> varchar,查询时 varchar —>Java Account Object

@MappedTypes({Account.class}) //指定java中的类型
@MappedJdbcTypes({JdbcType.VARCHAR}) //指定数据库中的数据类型
public class MyTypeHandler<E extends Object> extends BaseTypeHandler<E> {

    private Class<E> type;

    public MyTypeHandler(Class<E> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        String jsonStr = JSON.toJSONString(parameter);
        ps.setString(i, jsonStr);
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String accountStr = rs.getString(columnName);
        Account account = JSON.parseObject(accountStr, Account.class);
        return (E) account;
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String accountStr = rs.getString(columnIndex);
        Account account = JSON.parseObject(accountStr, Account.class);
        return (E) account;
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String accountStr = cs.getString(columnIndex);
        Account account = JSON.parseObject(accountStr, Account.class);
        return (E) account;
    }
}

2.4 编写完自定义类型处理器,那么编写查询与新增sql,并指定类型处理器即可。
在这里插入图片描述

MyBatis 提供了类型转换器(TypeHandler)机制,允许开发者自定义 Java 类型与数据库类型之间的转换逻辑。在处理 JSON 数据时,可以通过编写特定的 `TypeHandler` 来实现 Java 对象与数据库中的 JSON 类型(如 MySQL 的 JSON 类型)之间的自动转换。 ### 创建自定义 TypeHandler 假设使用的是 MySQL 数据库,并且数据库字段类型为 `JSON`,Java 中使用 `com.fasterxml.jackson.databind.JsonNode` 来表示 JSON 数据。以下是一个自定义 `TypeHandler` 的实现示例: ```java import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class JsonNodeTypeHandler extends BaseTypeHandler<JsonNode> { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public void setNonNullParameter(PreparedStatement ps, int i, JsonNode parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.toString()); } @Override public JsonNode getNullableResult(ResultSet rs, String columnName) throws SQLException { String json = rs.getString(columnName); if (json == null) { return null; } try { return objectMapper.readTree(json); } catch (Exception e) { throw new SQLException("Error parsing JSON from column " + columnName, e); } } @Override public JsonNode getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String json = rs.getString(columnIndex); if (json == null) { return null; } try { return objectMapper.readTree(json); } catch (Exception e) { throw new SQLException("Error parsing JSON from column index " + columnIndex, e); } } @Override public JsonNode getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String json = cs.getString(columnIndex); if (json == null) { return null; } try { return objectMapper.readTree(json); } catch (Exception e) { throw new SQLException("Error parsing JSON from callable statement", e); } } } ``` ### 注册 TypeHandler 在 MyBatis 配置文件中注册该 `TypeHandler`,或者在映射文件中指定它。以下是全局注册的方式: ```xml <typeHandlers> <typeHandler handler="com.example.JsonNodeTypeHandler" javaType="com.fasterxml.jackson.databind.JsonNode"/> </typeHandlers> ``` ### 在映射文件中使用MyBatis 的 XML 映射文件中,可以像使用其他类型一样使用该 `TypeHandler`。例如: ```xml <mapper namespace="com.example.UserMapper"> <resultMap id="userResultMap" type="com.example.User"> <result property="userData" column="user_data" typeHandler="com.example.JsonNodeTypeHandler"/> </resultMap> <select id="selectUserById" resultMap="userResultMap"> SELECT * FROM users WHERE id = #{id} </select> </mapper> ``` ### 自动映射与复杂 SQL 当 SQL 查询变得复杂时,可以使用 `resultMap` 标签来定义自定义的结果集映射规则。这在处理多表联查或嵌套对象时非常有用。例如,在一对一或多对多关系中,可以结合 `resultMap` 和 `TypeHandler` 来处理 JSON 数据。[^3] ### 总结 通过自定义 `TypeHandler`,可以轻松地在 MyBatis 中处理 JSON 数据。这种方式不仅适用于简单的 JSON 字段映射,还可以扩展到复杂的业务场景中,如多表联查和嵌套对象的映射。[^1]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值