场景:使用数据库存储表情,需要使用utf8mb4字符集。MySQL在5.5.3之后增加了utf8mb4字符编码。utf8mb4是utf8的超集并完全兼容utf8,能够用四个字节存储更多的字符。而utf8是utf8mb3的别名。标准的UTF-8字符集编码是可以用1~4个字节去编码21位字符,但是MySQL其实实现的utf8只是使用3个字节而已,utf8mb4才是真正意义上的utf8。
报错信息:
Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x8F\xA0' for column 'test_introduce' at row 1
问题:这是字符集不兼容的问题。
根据博主文章,字符集优先级: 字段字符集 > 表的字符集 > 库的字符集
源码借鉴于【morris131】博主。 JDBC源码:
if (realJavaEncoding.equalsIgnoreCase("UTF-8") || realJavaEncoding.equalsIgnoreCase("UTF8")) {
boolean useutf8mb4 = CharsetMapping.UTF8MB4_INDEXES.contains(this.session.getServerDefaultCollationIndex());
if (!this.useOldUTF8Behavior.getValue()) {
if (dontCheckServerMatch || !this.session.characterSetNamesMatches("utf8") || (!this.session.characterSetNamesMatches("utf8mb4"))) {
execSQL(null, "SET NAMES " + (useutf8mb4 ? "utf8mb4" : "utf8"), -1, null, false, this.database, null, false);
this.session.getServerVariables().put("character_set_client", useutf8mb4 ? "utf8mb4" : "utf8");
this.session.getServerVariables().put("character_set_connection", useutf8mb4 ? "utf8mb4" : "utf8");
}
} else {
execSQL(null, "SET NAMES latin1", -1, null, false, this.database, null, false);
this.session.getServerVariables().put("character_set_client", "latin1");
this.session.getServerVariables().put("character_set_connection", "latin1");
}
this.characterEncoding.setValue(realJavaEncoding);
}
在获取mysql的服务器参数后,解析字符集编码 character_set_server = utf8时,执行SET NAMES utf8 character_set_server = utf8mb4时,执行SET NAMES utf8mb4
问题复现:
sql:
SET NAMES utf8;
REPLACE INTO t_test (test_introduce) VALUES ('??🏠')
INSERT INTO t_thread_vote_cfg (vote_introduce) VALUES ('??🏠') 1366 - Incorrect string value: '\xF0\x9F\x8F\xA0' for column 'test_introduce' at row 1
解决思路
1、首先确定检查参数,查看java传入数据库是是否发生转译,确认参数。
2、确定当前数据库字符集
3、查看字段的字符集
show full columns from test
show full columns from (表名)
4、查看库字符集,右击库名编辑数据库就可以看到
5、当你发现这些都没有问题的时候,就应该看看你的数据库配置文件的问题。
查看服务器字符集 show variables like ‘%character%’;
我这里是更改之后的所以是utf8mb4,如果是utf8,则在my.cnf文件中添加配置,重启服务
character_set_server = utf8mb4
———————————————— 借鉴文章链接:https://blog.csdn.net/u022812849/article/details/125893345
|