首页 前端知识 Spring Boot 中如何处理存取 MySQL 中 JSON 类型的字段

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

2024-06-02 09:06:07 前端知识 前端哥 92 586 我要收藏

请添加图片描述

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

已知在 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 类型的字段了:

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

在这里插入图片描述

转载请注明出处或者链接地址:https://www.qianduange.cn//article/10562.html
标签
评论
发布的文章

vue学习计划

2024-06-08 18:06:08

fastjson1.2.24-RCE漏洞复现

2024-06-08 09:06:33

JsonPath用法详解

2024-06-08 09:06:55

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!