Spring Boot 中如何处理存取 MySQL 中 JSON 类型的字段

请添加图片描述

👨🏻‍💻 热爱摄影的程序员
👨🏻‍🎨 喜欢编码的设计师
🧕🏻 擅长设计的剪辑师
🧑🏻‍🏫 一位高冷无情的全栈工程师
欢迎分享 / 收藏 / 赞 / 在看!

已知在 MySQL 中有表 test_json_type,定义如下:

-- 测试JsonType
drop table if exists test_json_type;
create table test_json_type
(
    test_id     bigint not null primary key comment 'testID',
    ids         json not null comment 'ids',
) engine innodb comment '测试JsonType表';

在 MyBatis-Plus 中,可以通过实现 TypeHandler 接口来创建自定义的类型处理器,用于处理 Java 类型和 JDBC 类型之间的转换。

为了处理 JSON 字符串和 Java 数组之间的转换,创建一个名为 JsonTypeHandler 的类,并实现 TypeHandler 接口,将 Java 中的字符串数组转换为 JSON 字符串存储到 MySQL 数据库中,以及将数据库中的 JSON 字符串转换回 Java 字符串数组。

MyBatis-Plus 官网-字段类型处理器

首先,需要添加 Jackson 库到项目中,因为我们将使用它来序列化和反序列化 JSON:

<!-- 添加Jackson依赖 -->  
<dependency>  
    <groupId>com.fasterxml.jackson.core</groupId>  
    <artifactId>jackson-databind</artifactId>  
    <version>2.13.0</version>  
</dependency>

然后,创建 JsonTypeHandler 类。使用 Jackson 库的 ObjectMapper 来执行 JSON 序列化和反序列化。setNonNullParameter 方法用于将 Java 数组转换为 JSON 字符串并设置到 PreparedStatement 中,而 getNullableResult 方法用于从 ResultSet 或 CallableStatement 中检索 JSON 字符串并转换回 Java 数组:

public class JsonTypeHandler<T> extends BaseTypeHandler<T> {  
  
    private static final ObjectMapper objectMapper = new ObjectMapper();  
  
    @Override  
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {  
        try {  
            if (parameter instanceof String[]) {  
                String json = objectMapper.writeValueAsString((String[]) parameter);  
                ps.setString(i, json);  
            } else {  
                throw new IllegalArgumentException("Cannot convert type " + parameter.getClass().getName() + " to JSON");  
            }  
        } catch (JsonProcessingException e) {  
            throw new RuntimeException("Error converting to JSON", e);  
        }  
    }  
  
    @Override  
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {  
        String json = rs.getString(columnName);  
        if (json != null) {  
            try {  
                return (T) objectMapper.readValue(json, String[].class);  
            } catch (IOException e) {  
                throw new RuntimeException("Error converting JSON to type", e);  
            }  
        }  
        return null;  
    }  
  
    @Override  
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {  
        String json = rs.getString(columnIndex);  
        if (json != null) {  
            try {  
                return (T) objectMapper.readValue(json, String[].class);  
            } catch (IOException e) {  
                throw new RuntimeException("Error converting JSON to type", e);  
            }  
        }  
        return null;  
    }  
  
    @Override  
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {  
        String json = cs.getString(columnIndex);  
        if (json != null) {  
            try {  
                return (T) objectMapper.readValue(json, String[].class);  
            } catch (IOException e) {  
                throw new RuntimeException("Error converting JSON to type", e);  
            }  
        }  
        return null;  
    }  
}

接下来,需要在 MyBatis 的映射文件或注解中指定使用这个自定义的类型处理器。如果使用 XML 映射文件,可以这样做:

<resultMap id="productResultMap" type="com.example.Product">  
    <id column="id" property="id"/>  
    <result column="spec_ids" property="specIds" typeHandler="com.example.JsonTypeHandler"/>  
    <!-- 其他字段映射 -->  
</resultMap>

如果使用注解,需在实体类开启映射 autoResultMap = true 并且在字段上使用 @TypeHandler 注解:

@Data
@EqualsAndHashCode(callSuper = true)
@TableName(value = "test_json_type", autoResultMap = true)
public class TestJsonType extends BaseEntity {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * testID
     */
    @TableId(value = "test_id")
    private Long testId;

    /**
     * ids
     */
    @TableField(value = "ids", typeHandler = JsonTypeHandler.class)
    private String[] ids;
}

然后就可以正常地存取 JSON 类型的字段了:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 15
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程洪同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值