1.背景
Mysql5.7.8版本以后新增的功能,Mysql提供了一个原生的Json类型,Json值将不再以字符串的形式存储,而是采用一种允许快速读取文本元素(document elements)的内部二进制(internal binary)格式,并提供了不少内置函数,通过计算列,甚至还可以直接索引json中的数据。
2.数据库基本操作
1.表结构
新建表
CREATE TABLE `table_name` (
`id` INT UNSIGNED NOT NULL,
`business_attr` JSON NOT NULL,
PRIMARY KEY (`id`)
);
新增json类型字段
alter table table_name add column `business_attr` JSON NULL;
2.插入操作
在json数据列提供json格式的字符串即可
insert into table_name values(1,'{"attr_key1":"attr_value1","attr_key2":"attr_value2"}');
如果是字符串,可以通过cast函数转成json
insert into table_name values(1,CAST('{"attr_key1":"attr_value1","attr_key2":"attr_value2"}', as JSON));
3.更新操作
1.json_set
更新json字段
update table_name set business_attr=json_set('{"num":1,"name":"abc"}','$.num',2,'$.age',16,'$.class.id',1) where id=1;
-
JSON_SET(json_doc, path, val[, path, val] ...)
-
path中$就代表整个doc,然后可以用javascript的方式指定对象属性或者数组下标等.
-
值存在就修改,值不存在就设置,路径不存在将直接被忽略。
2.json_merge_patch
更新json字段
update table_name set business_attr=JSON_MERGE_PATCH(IFNULL(business_attr,json_object()),JSON_OBJECT('attr_key1',CAST('attr_value1' as JSON))) where id=1;
MySQL JSON_MERGE_PATCH()
函数返回一个由参数指定的多个 JSON 文档合并后的 JSON 文档。JSON_MERGE_PATCH()
执行的是替换合并,即在相同键值时,只保留后面的值。
3.json_insert
插入json字段
-
JSON_INSERT(json_doc, path, val[, path, val] ...)
-
如果不存在对应属性则插入,否则不做任何变动
4.删除操作
json_remove
方法删除某个属性
update table_name set business_attr=JSON_REMOVE(business_attr,'$.attr_key1') where id=1;
-
JSON_REMOVE(json_doc, path[, path] ...)
-
如果存在则删除对应属性,否则不做任何变动
5.查询操作
1.使用json_extract
函数查询,获得doc中某个或多个节点的值。
JSON_EXTRACT(json_doc, path[, path] ...)
SELECT JSON_EXTRACT(business_attr, '$.attr_key1') where id=1;
2.使用 字段->'$.json属性'进行查询条件
mysql5.7.9开始增加了一种简写方式:column->path
SELECT business_attr->'$.attr_key1' where id=1;
JSON相关函数参考
3.结合Mybatis使用
TypeHandler
是 Mybatis 中用来处理 Java 类型与数据库类型之间的映射的一个接口。当你需要自定义数据类型的映射规则时,就需要实现这个接口。
例如,需要将新增的JSON字段business_attr映射成Map类型,就需要实现一个MapTypeHandler,用来处理Java中Map和数据JSON字段类型的转换。
注意\] 在自定义类型转换逻辑的情况下,需要显式的配置启用autoResultMap,从而自动映射sql查询结果到相应的实体对象。
#### 1.Java实体类配置
如前所述,需要自定义一个MapTypeHandler,并在JSON类型字段上配置,同时启用autoResultMap。
```
@TableName(value = "table_name", autoResultMap = true)
public class TableName {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
@TableField(typeHandler = MapTypeHandler.class)
private Map