关于MySQL数据库和Java JDBC连接编码。
数据库已转换为utf8mb4和utf8mb4_unicode_ci,如图所示,这是来自JDBC连接的SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
的结果。
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
在MySQL Workbench和直接连接到数据库的终端上,我可以看到Unicode字符í
,其正确的十六进制值为c3 ad
+------------------------------+
| HEX(location.name) |
+------------------------------+
| C3AD |
+------------------------------+
JDBC连接设置:
useUnicode=true&characterEncoding=UTF-8
使用HikariCP和
的配置 config.addDataSourceProperty("useUnicode", "true");
config.addDataSourceProperty("characterEncoding", "utf-8");
config.setConnectionInitSql("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");
使用mysql-connector-java:8.0.11
从使用JDBC连接查询相关表的结果来看,í
字符在Postman中作为�
返回。并且在Postman中以
?
的形式返回。
根据stackoverflow.com/questions/38363566,这会导致我相信阅读期间的连接不是UTF-8,我将如何检测到它?
如果需要,数据库和应用程序已重置为应用设置。
答案 0 :(得分:2)
characterEncoding = utf-8与utf8mb4不兼容。在您的JDBC URL中使用character_set_server=utf8mb4
或config.addDataSourceProperty("character_set_server", "utf8mb4");
。完全不要使用characterEncoding。
从MySQL Connection / J开发人员指南→使用字符集→Setting the Character Encoding:
…要将4字节UTF-8字符集与Connector / J一起使用,使用
character_set_server=utf8mb4
配置MySQL服务器,并将characterEncoding
保留在Connector / J连接字符串之外。
并在其下:
警告
为了使用
utf8mb4
字符集进行连接,服务器必须配置character_set_server=utf8mb4
;如果不是这种情况,则在连接字符串中将UTF-8
用于characterEncoding
时,它将映射到MySQL字符集名称utf8
,这是{{1}的别名}。
答案 1 :(得分:0)
除了遵循VGR的帮助外,我还使用普通的PrintWriter发送不允许UTF-8编码的响应。 代替
PrintWriter out = response.getWriter();
out.println(res);
out.flush();
替换为
response.getOutputStream().write(res.toString().getBytes("UTF-8"));
答案 2 :(得分:0)
“ í
返回字符�
”与“ 返回
?
”是一个不同的问题
前者通常在í
的字节未编码为UTF-8时发生。请注意,在MySQL中,对于该字符和所有其他欧洲字符的正确编码,utf8mb3和utf8mb4相同。修复连接(如VGR所讨论)可能无法修复它。仅当浏览器未设置为UTF-8(Unicode)时,才会出现黑色菱形。
“ poo of poo”(堆便便)仅在utf8mb4中可用,而在utf8mb3中不可用。因此,假设客户端正确使用十六进制F09F92A9
,则连接参数(请参见VGR)可能是导致问题的原因。
(您提供的链接中有更多讨论。)