JSON 作为一种通用的数据格式,由于其结构灵活、可拓展等特点,在某些场景下我们也会直接将数据以 JSON 格式存储到数据库中,例如 数据结构不固定、数据具有复杂的嵌套结构时,具体见我写的这篇文章 使用JSON存储数据的场景。
本文介绍 SpringBoot 项目中应如何去存储 JSON 数据和进行查询。
1.JSON数据的存储与查询
1.1.数据库
存储 JSON 数据,数据库字段可以使用 json 类型,但是要求 mysql 版本 5.7+ 才可以使用;
如果是 mysql 5.7 以前的版本,可以使用 varchar。
建议使用 json 字段类型,有如下好处:
- MySQL 会自动验证存储的数据是否为有效的 JSON 格式。如果数据格式无效,MySQL 会拒绝插入或更新操作。
- MySQL 提供了丰富的 JSON 函数(如 JSON_EXTRACT、JSON_SET、JSON_REMOVE 等),可以直接对JSON 字段进行查询和操作。
有如下的 user 表, 其中的 settings 字段用于存储用户的个性化设置。
因为不同用户的个性化设置的参数可能是不同的,同时为了方便后续拓展新的参数,这里使用一个字段去存储 个性化设置的 JSON数据。
CREATE TABLE `user` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(64) DEFAULT NULL,`settings` json DEFAULT NULL,PRIMARY KEY (`id`)
)
1.2.实体类
实体类中,对应的字段为 String 类型。
数据库查询和更新时,不需要做什么特别处理,就把这个字段当作字符串就行。
@TableName(value ="user")
@Data
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private String settings;
}
1.3.接口返回的Vo对象
接口返回的 Vo 对象中 对应字段用 String 类型,同时字段要加注解@JSONRawValue
。
加了注解@JSONRawValue
后,SpringMVC 框架序列化 Vo 对象时,会将此字段的值作为 JSON 对象 直接嵌入到生成的 JSON 中。
关于注解
@JSONRawValue
,详见后文的说明。
查询数据时,直接将实体类字段的值 copy 到 Vo对象的字段即可。
import com.fasterxml.jackson.annotation.JsonRawValue;@Data
public class UserVo implements Serializable {private Long id;private String name;@JsonRawValueprivate String settings;private static final long serialVersionUID = 1L;
}
接口响应数据:可以看到 settings 被解析为 JSON 对象。
{"code": 0,"data": {"id": 1,"name": "Wilt","settings": {"theme": "dark","notifications": {"sms": false,"email": true}}},"message": "ok"
}
1.4.接口传参Bo对象(或DTO)
接口传参 Bo 对象中,对应字段为 Object 类型,这样前端传任意结构的对象都可以接收。
更新数据时,将 Bo 对象中的这个 Object 字段序列化为 JSON 字符串后,将此 JSON 字符串保存到数据库中。
@Data
public class UserBo implements Serializable {private Long id;private String name;private Object settings;private static final long serialVersionUID = 1L;
}
2.@JSONRawValue注解
@JSONRawValue
是 Jackson 库(com.fasterxml.jackson)中的注解。
2.1.关于 Jackson 库
Jackson 是一个用于 JSON 处理的库,Spring Boot 默认使用 Jackson 库做 JSON 的处理(序列化、反序列化)。
在 Spring Boot 项目中,Jackson 库通常是有导入的,所以@JSONRawValue
注解是可以直接用的,不需要额外导入包。
2.2.注解说明
在上文中,我们在接口返回的 Vo 对象的 settings 字段上加了@JSONRawValue
。
我们知道,SpringMVC 框架在处理标注有@ResponseBody
的接口响应时,会将接口返回的 Vo 对象序列化为 JSON 字符串后,将其设置为 HTTP 响应的主体。
settings 字段上加有@JSONRawValue
,则当框架序列化 Vo 对象时,该字段的值作为原始的 JSON 数据(JSON 对象)直接嵌入到生成的 JSON 中,而不是将其作为字符串处理。
当 settings 字段上加有@JSONRawValue
时,接口响应数据:settings 被解析为 JSON 对象。
{"code": 0,"data": {"id": 1,"name": "Wilt","settings": {"theme": "dark","notifications": {"sms": false,"email": true}}},"message": "ok"
}
没有加注解,接口响应数据:settings 被作为字符串处理。
{"code": 0,"data": {"id": 1,"name": "Wilt","settings": "{\"theme\": \"dark\", \"notifications\": {\"sms\": false, \"email\": true}}"},"message": "ok"
}
如果有帮助的话,可以点个赞支持一下嘛
🙏