由于对mysql的函数并不了解,之前遇到了一个场景:
mysql表中有一个字段res_content 是一个由
longtext类型
(可以理解为一个更长的
varchar
)保存的巨大的
JSON
对象,但是,由于录入的疏忽,导致这个json对象中的有一个属性值错误,需要重新修改这个json对象的属性值,于是,我将整个json对象,也就是res_content字段重新替换了一遍。=。= |||
一个json中小小的属性需要更新,却要替换整个json对象,仅仅因为它在数据库中是以一个字段存储的!!?这也太傻吊了!
这样做虽然简单粗暴,但很明显不符合我
追求完美
的性格,既然只有一个属性出错,那为什么不能直接替换这个JSON中具体的属性呢?而且这样的解决办法,如果处理上千万条JSON还可以减小mysql的性能开销,岂不美哉!?
当时并没有及时想到mysql函数,实际上mysql现在已经支持了大量的JSON字符串的操作函数,可以支持基本的需求。这也是我偶然间浏览
我的关注
里面的博文一个大神提供给我的思路:《
mysql替换某字段中的部分值
》,所以非常感谢这位博主。
不过,这个博主的文章只是替换已知字符串的值,比如 :http 改成 https,但对于json字符串,我们要想替换key所对应的value就涉及到两步:查询和替换,很明显,他这篇博客并不符合我的需求,不过确实给我提供了一个查阅mysql函数的思路。下面就来简单说说MySQL中用于替换JSON属性值的这个函数:
JSON_REPLACE(
json_doc
,
path
,
val
[,
path
,
val
] ...)
。
JSON_REPLACE():
官方的第一句解释是:Replaces existing values in a JSON document and returns the result。就冲这句话,基本可以锁定它就是我要找的解决方案。我们来看一下官方的示例:
mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
+-----------------------------------------------------+
| JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') |
+-----------------------------------------------------+
| {"a": 10, "b": [2, 3]} |
+-----------------------------------------------------+
上面的例子很好理解,
首先,它定义了一个JSON字符串变量,然后通过JSON_REPLACE函数将这个变量中的属性a的值由1 改为了10,然后将属性c的值改为了‘[true, false]’,但由于json字符串中并没有属性 c 因此只有属性 a 修改成功了
。(这里需要注意,mysql函数仅仅是做数据转换,并不涉及到真正的增删改查,因此还需要配合具体的
UPDATE
才能够真正更新数据)
看过这个例子之后,我思考了一下我的应用场景,只需要在更新的sql语句中调用
JSON_REPLACE
函数,将json对象所对应的字段比作上面的JSON字符串变量,然后通过 ‘$xxx’ 匹配到我所希望修改的值,然后就可以成功修改JSON对象中的属性了。
现在我有一张
employee表
,它的
last_name
字段是一个简单的JSON字符串:
现在,我希望修改
emp_id = 1
的记录,将这条记录中last_name中的
name
改成“
Harry
”,
gender
改成 “
女
”。于是我执行了下面的SQL:
UPDATE employee
SET last_name = json_replace(last_name, '$.name', "Harry", "$.gender", "女")
WHERE emp_id = 1;
这里注意,我特意将
"$.gender"
写为双引号,目的就是为了测试这样的通配是否可以生效,执行成功后,查询结果如下:
可以看到,last_name字段中的name属性已经修改成Harry,gender也被修改成了“女”,因此通配符 用双引、单引都是可以的。
除了JSON_REPLACE()函数,还有很多其他的json函数,如JSON_REMOVE()等,具体函数用法可以查看官方文档:
https://dev.mysql.com/doc/refman/5.7/en/json-functions.html
里面还贴心的将用法进行了归类:
但是,这些函数应该都对mysql数据库的版本比较敏感,一般对
MySQL5.7
以上的版本支持比较理想,个别函数可能需要5.7.8以上,我的数据库是5.7.23,因此JSON_REPLACE()用着还可以,如果你的版本在5.7以下,就得好好看看是否支持这些函数了。
简单查看MySQL数据库的版本:SELECT VERSION();
综上,就是关于如何修改JSON字符串中属性值的函数
JSON_REPLACE()
的简单介绍,欢迎文末留言。
JSON
_SET(
json
_doc, path, val[, path, val] ...)
JSON
_INSERT(
json
_doc, path, val[, path, val] ...)
JSO...
JSON
是 JavaScript Object Notation(JavaScript 对象表示法)的缩写,是一个轻量级的,基于文本的,跨语言的数据交换格式。易于阅读和编写。数
值
:十进制数,不能前导0,可以为负数或小数,还可以为e或E表示的指数。字符串:字符串必须用双引号括起来。布尔
值
:true、false。数组:一个由零或多个
值
组成的有序序列。每个
值
可以为任意类型。数组使用方括号[ ]括起来,元素之间用逗号分隔。对象:一个由零或者多个键
值
对组成的无序集合。
MySQL
5.7.8中引入了
json
字段,这种类型的字段使用的频率比较低,但是在实际操作中,有些业务仍然在用,我们以此为例,介绍下
json
字段的操作方法:
还是从例子看起:
mysql
> create table test1(id int,info
json
);
Query OK, 0 rows affected (0.02 sec)
mysql
> insert into test1 values (1,'{name:yeyz,age:26}'),(2,'{name:zhangsan,age:30}'),(3,'{name:lisi,age:35}');
需求描述:在看
mysql
中关于
json
的内容,通过
json
_
replace
函数
可以实现对
json
值
的替换,在此记录下.操作过程:1.查看带有
json
数据类型的表
mysql
> select * from tab_
json
;+----+---------------------------------------------------------------------------------...
11.10.9
JSON
_
REPLACE
(
json
_doc,path,val[,path,val] ...)
函数
JSON
_
REPLACE
(
json
_doc,path,val[,path,val] ...)
函数
用于更新
JSON
数据中指定Key的数据。使用示例如下:
mysql
> SELECT
JSON
_
REPLACE
(content,'$.age',20) FROM test...
JSON
.stringify(value,
replace
r, space)
value any JavaScript value, usually an object or array.
replace
r an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or ' '),
it contains the characters used to indent at each level.
This method produces a
JSON
text from a JavaScript value.
When an object value is found, if the object contains a to
JSON
method, its to
JSON
method will be called and the result will be
stringified. A to
JSON
method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The to
JSON
method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.to
JSON
= function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
You can provide an optional
replace
r method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the
replace
r parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the
replace
r array are
stringified.
Values that do not have
JSON
representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be
replace
d with null. You can use
a
replace
r function to
replace
those with
JSON
values.
JSON
.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text =
JSON
.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text =
JSON
.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text =
JSON
.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
// text is '["Date(---current time---)"]'
JSON
.parse(text, reviver)
This method parses a
JSON
text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData =
JSON
.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
return value;
myData =
JSON
.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
return value;
This is a reference implementation. You are free to copy, modify, or
redistribute.
MySQL
的
json
查询之
json
_insert、
json
_merge_patch、
json
_merge_preserve、josn_remove、
json
_
replace
、
json
_set
json
_insert就是向
json
中插入,如果不存在则插入,存在则忽略
json
_
replace
就是替换
json
中的项,如果不存在则忽略,存在则替换
json
_set结合前面俩个,存在则替换,不存在则插入
json
_merge_patch多个
json
进行合并,相同键名,后面的覆盖前面的,如果
值
是对象,则递归进行处
//这是直接用raplace直接替换的 当作字符串替换
update
cxr_region_performance
set district_manager=
replace
(district_manager, 'aa', 'bb')
where
JSON
_OVERLAPS(district_manager -> '$[*].cxrEmployeeName', cast('[
]' as
json
));