MySQL 5.5 连接器/J 字符集编码 (utf8mb4) 问题

Posted

技术标签:

【中文标题】MySQL 5.5 连接器/J 字符集编码 (utf8mb4) 问题【英文标题】:MySQL 5.5 Connector/J CharacterSet Encoding (utf8mb4) Issue 【发布时间】:2013-07-04 15:06:54 【问题描述】:

我正在尝试将 utf8mb4 字符串正确存储到 mysql 5.5.30 中。我们正在使用 ConnectorJ 5.1.18。

根据文档,ConnectorJ 应该根据 character_set_server 变量自动检测字符编码...

但是,据我所知,它始终默认为

SET NAMES latin1 而不是 SET NAMES utf8mb4

connector-j profiler 的日志输出:

2013 年 7 月 6 日星期六 15:45:20 CDT 信息:分析器事件:[QUERY] at java.sql.DriverManager.getConnection(DriverManager.java:579) 持续时间:1 毫秒,连接 ID:57,语句 ID:3,结果集ID:4,消息:/ * mysql-connector-java-5.1.18(修订版:tonci.grgin@oracle.com-20110930151701-jfj14ddfq48ifkfq)*/显示变量,其中变量名='语言'或变量名='net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_pa​​cket' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode ' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect' 2013 年 7 月 6 日星期六 15:45:20 CDT 信息:分析器事件:java.sql.DriverManager.getConnection(DriverManager.java:579) 处的 [FETCH] 持续时间:0 毫秒,连接 ID:57,语句 ID:3,结果集ID:4 2013 年 7 月 6 日星期六 15:45:20 CDT 信息:分析器事件:[QUERY] at java.sql.DriverManager.getConnection(DriverManager.java:579) 持续时间:0 毫秒,连接 ID:57,语句 ID:3,结果集ID:5,消息:/* mysql-connector-java-5.1.18(修订:tonci.grgin@oracle.com-20110930151701-jfj14ddfq48ifkfq)*/SELECT @@session.auto_increment_increment 2013 年 7 月 6 日星期六 15:45:20 CDT 信息:分析器事件:java.sql.DriverManager.getConnection(DriverManager.java:579) 处的 [FETCH] 持续时间:0 毫秒,连接 ID:57,语句 ID:3,结果集ID:5 2013 年 7 月 6 日星期六 15:45:20 CDT 信息:分析器事件:[QUERY] at java.sql.DriverManager.getConnection(DriverManager.java:579) 持续时间:0 毫秒,连接 ID:57,语句 ID:4,结果集 ID:6,消息:显示排序 2013 年 7 月 6 日星期六 15:45:20 CDT 信息:分析器事件:java.sql.DriverManager.getConnection(DriverManager.java:579) 处的 [FETCH] 持续时间:3 毫秒,连接 ID:57,语句 ID:4,结果集ID:6 2013 年 7 月 6 日星期六 15:45:20 CDT 信息:分析器事件:[QUERY] at java.sql.DriverManager.getConnection(DriverManager.java:579) 持续时间:1 毫秒,连接 ID:57,语句 ID:999,结果集 ID:0,消息:SET NAMES latin1

SHOW VARIABLES 调用的输出如下:

character_set_client utf8 character_set_connection utf8 character_set_results utf8 character_set_server utf8mb4

服务器当前正在运行,因此我只是运行了更新 character_set_server 值

SET GLOBAL
SET
语句。

更新: 当我更改 my.cnf 中的 character_set_server 值并重新启动服务器时,ConnectorJ 会完全按照预期检测到 utf8mb4。

当我使用 SET GLOBAL 手动设置值时,ConnectorJ 继续使用 Latin1。

有人知道为什么会这样吗?有什么方法可以以 ConnectorJ 检测到的方式更新字符集,而无需使 mysql 脱机?

【问题讨论】:

【参考方案1】:

我也有类似的问题。过去,来自 ConnectorJ 的客户端字符集握手使用常规/不完整的 utf8 字符集而不是 utf8mb4

https://dev.mysql.com/doc/relnotes/connector-j/en/news-5-1-13.html

修复了自 5.1.12 版以来发现的错误。 Connector/J 现在自动检测配置了 character_set_server=utf8mb4 的服务器,或者将使用 characterEncoding=... 传递的 Java 编码 utf-8 视为 SET NAMES= 建立连接时调用的 utf8mb4。 (错误 #54175)

但是,升级 ConnectorJ 并没有解决任何问题。顺便说一句,感谢您发现更改配置文件解决了问题,而在运行时更改值却没有。这为我节省了很多时间。

对于任何因任何原因无法重新启动服务器的相同问题的人。我建议(与 MySQL 文档相反,当你想使用 utf8mb4 时从连接字符串中省略 characterEncoding)将 characterEncoding=UTF-8 添加到连接字符串并在你遇到问题的连接上手动执行 SET NAMES utf8mb4与。

【讨论】:

以上是关于MySQL 5.5 连接器/J 字符集编码 (utf8mb4) 问题的主要内容,如果未能解决你的问题,请参考以下文章

mysql 5.5支持中文编码 ubuntu

mysql左外连接

php+mysql 解决emoji问题

JDBC 和 Mybatis连接mysql数据库的时候,设置字符集编码

java连接数据库读取数据出现乱码

5 左连接导致查询超时,mysql 5.5