mysql 5.7 emoji问题

错误:

1
2
3
4
5
6
7
8
9
Caused by: java.sql.SQLException: Incorrect string value: '\xF6\x9D\x98\x84' for column 'column' at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)

原因:

mysql 编码为 utf-8造成, utf-8只能存储1-3个字节,而emoji表情是4个字节

1
2
#查看当前mysql的编码
show variables like 'character%';

解决:

utf8mb4是utf8的新版,兼容utf8

1
2
3
4
5
6
7
8
9
[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
修改后重启mysql服务

这是修改后的正确 mysql 配置

cmd-markdown-logo


坑:

其实在搞得时候由于mysql集群的复杂性,重启风险很大,尝试过修改表和列的编码方式,但是基本没效果。

修改列和表的utf8mb4后,手动insert 语句是可以插入的,rest_api也可以正常返回。

只要过Spring Boot程序进行保存就会报错

1
2
3
4
5
// 这两种方式都无效

jdbc:mysql://127.0.0.1:3306/xxx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull

jdbc:mysql://127.0.0.1:3306/xxx?useUnicode=true&zeroDateTimeBehavior=convertToNull


似乎是由于在启动的时候会查找mysql默认的编码方式,再返回到程序,通过程序来进行check是否满足插入条件。

只能修改mysql级别的characterEncoding才可以正常保存