目录
一、MySQL中如何保存JSON类型的数据
1.1 建表
1.2 保存一条带json的记录
1.3 查询
二、Springboot操作当前数据库表
2.1 方式一(推荐)
2.2 方式二
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式 。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。它易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
一、MySQL中如何保存JSON类型的数据
1.1 建表
CREATE TABLE `steel` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`steel_grade` json NOT NULL COMMENT '钢种,json数组',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
1.2 保存一条带json的记录
INSERT INTO steel (steel_grade)
VALUES ('["Q235", "PWB", "P610L"]');
1.3 查询
SELECT * FROM steel;
当需要检索JSON类型字段中数据的某个具体值时,可以使用“->”和“->>”符号。
SELECT steel_grade -> '$[0]'
FROM steel;
SELECT steel_grade ->> '$[0]'
FROM steel;
其中->>则是反序列化后的结果。
二、Springboot操作当前数据库表
导入依赖这里就不赘述了,然后就是Application.yaml配置文件,这些都是和原来一样的。
我们通过代码生成器,自动生成实体类、controller、service、mapper这些基本结构。
话不多说,我们直接看关键的部分。
2.1 方式一(推荐)
实体类
@Data
@TableName("steel")
@ApiModel(value = "Steel对象", description = "")
public class Steel implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@ApiModelProperty("钢种,json数组")
@TableField("steel_grade")
private String steelGrade;
}
我们可以用String类型去接收数据库的JSON类型。因为JSON就是以字符串的形式存储的嘛。
controller
@Api(tags = "钢信息")
@RestController
@RequestMapping("/steel")
public class SteelController {
@Resource
private SteelService steelService;
@ApiOperation("新增一条数据,测试保存json")
@PostMapping("save")
public Result<String> save(String[] steelGrade){
steelService.saveData(steelGrade);
return Result.success();
}
@ApiOperation("查询数据")
@PostMapping("selectOne")
public Result<Steel> selectSteelById(Integer id){
Steel steel = steelService.selectSteelById(id);
return Result.success(steel);
}
}
service
@Service
public class SteelServiceImpl extends ServiceImpl<SteelMapper, Steel> implements SteelService {
@Transactional
@Override
public void saveData(String... steelGrade) {
String jsonString = JSON.toJSONString(steelGrade);
Steel steel = new Steel();
steel.setSteelGrade(jsonString);
baseMapper.insert(steel);
}
@Override
public Steel selectSteelById(Integer id) {
Steel steel = baseMapper.selectById(id);
String steelGrade = steel.getSteelGrade();
List<String> list = JSON.parseArray(steelGrade, String.class);
String str = "";
for (int i = 0; i < list.size(); i++) {
if (i == list.size() -1){
str += list.get(i);
}else {
str += list.get(i) + "、";
}
}
steel.setSteelGrade(str);
return steel;
}
}
存数据的时候,我们要将集合转成JSON字符串,进行序列化,这样才方便后面解析。
查询的时候,我们进行反序列化,由于存的是字符串类型的JSON数组,所有直接反序列化成数组即可。
测试保存
保存成功,数据增加了一条记录,对应的json数据格式正确。
测试查询
查询成功。
值得注意的是,因为我们保存的是json格式的,那么获取的时候也一定要进行反序列化,解析成我们需要的格式即可。
2.2 方式二
使用MybatisPlus提供的字段类型处理器。
具体的,实体类上按照如下设置即可。
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
private Long id;
...
/**
* 注意!! 必须开启映射注解
*
* @TableName(autoResultMap = true)
*
* 以下两种类型处理器,二选一 也可以同时存在
*
* 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
*/
@TableField(typeHandler = JacksonTypeHandler.class)
// @TableField(typeHandler = FastjsonTypeHandler.class)
private OtherInfo otherInfo;
}
注解对应了 XML 中写法为
<result column="other_info" jdbcType="VARCHAR" property="otherInfo" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
ok,我们在自己的项目中试验一下。
实体类
@Data
@TableName(value = "steel",autoResultMap = true)
@ApiModel(value = "Steel对象", description = "")
public class Steel implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@ApiModelProperty("钢种,json数组")
@TableField(value = "steel_grade",typeHandler = FastjsonTypeHandler.class)
private List<String> steelGrade;
}
controller
controller不变
service
service层不需要我们自己再转成json,或者解析json了。通过实体类的注解参数就帮我们搞定了。
@Service
public class SteelServiceImpl extends ServiceImpl<SteelMapper, Steel> implements SteelService {
@Transactional
@Override
public void saveData(String... steelGrade) {
Steel steel = new Steel();
steel.setSteelGrade(Arrays.asList(steelGrade));
baseMapper.insert(steel);
}
@Override
public Steel selectSteelById(Integer id) {
Steel steel = baseMapper.selectById(id);
List<String> steelGrade = steel.getSteelGrade();
steel.setSteelGrade(steelGrade);
return steel;
}
}
测试保存
测试查询
注意:查询出来的steelGrade集合的元素都带有双引号,说明返回的是JSON字符串格式,也意味着没有进行反序列化操作。我们还需要额外处理。
因此个人而言,我更倾向于方法一。