官方Mysql手冊鏈接
https://dev.mysql.com/doc/connectors/en/connector-j-reference-charsets.html
Notes
For Connector/J 8.0.12 and earlier: In order to use the utf8mb4 character set for the connection, the server MUST be configured with character_set_server=utf8mb4; if that is not the case, when UTF-8 is used for characterEncoding in the connection string, it will map to the MySQL character set name utf8, which is an alias for utf8mb3.
For Connector/J 8.0.13 and later:
When UTF-8 is used for characterEncoding in the connection string, it maps to the MySQL character set name utf8mb4.
If the connection option connectionCollation is also set alongside characterEncoding and is incompatible with it, characterEncoding will be overridden with the encoding corresponding to connectionCollation.
Because there is no Java-style character set name for utfmb3 that you can use with the connection option charaterEncoding, the only way to use utf8mb3 as your connection character set is to use a utf8mb3 collation (for example, utf8_general_ci) for the connection option connectionCollation, which forces a utf8mb3 character set to be used, as explained in the last bullet.
Warning
Do not issue the query SET NAMES with Connector/J, as the driver will not detect that the character set has been changed by the query, and will continue to use the character set configured when the connection was first set up.
文檔說的很清楚
提示
mysql-connector-java 版本在8.0.12之前的,包括8.0.12,服務端必須設置character_set_server=utf8mb4;如果不是的話,就算設置了characterEncoding=UTF-8,照樣會被設置為MYSQL的 utf8字符集,也就是utf8mb3。
對於8.0.13和以后的版本,如果設置了characterEncoding=UTF-8,他會映射到MYSQL的utf8mb4字符集。
如果connectionCollation 也和characterEncoding一起設置了,但是不兼容,characterEncoding會被connectionCollation的設置覆蓋掉。
由於沒有Java-Style的utfmb3對應的字符集名稱可以用在connection選項charaterEncoding上,唯一的設置utf8mb3的方式就是在連接選項設置utf8mb3 collation(例如utf8_general_ci),這會強制使用utf8mb3字符集,正如上文所述。
警告
不要通過Connector發起SET NAMES指令,因為driver不會檢測字符集是不是被查詢語句改動,並且當連接第一次建立之后,會繼續使用當時的字符集設置。
結論
對於網上的設置:
<property name="connectionInitSqls" value="set names utf8mb4;"/>
純屬扯淡。。
jdbc:mysql://localhost:3306/dbnameuseUnicode=true&characterEncoding=utf8
也是扯淡,
characterEncoding 要設置 為UTF-8。
MySQL Character Set Name | Java-Style Character Encoding Name |
---|---|
For 8.0.12 and earlier: utf8 | UTF-8 |
For 8.0.13 and later: utf8mb4 | UTF-8 |
Java-Style的字符集是UTF-8,而不是utf8
正確解決方法
改服務器配置吧,或者升級mysql-connector-java 到 8.0.13以后吧
測試情況
jdbc:mysql://localhost:3306/dbnameuseUnicode=true&characterEncoding=utf-8&connectionCollation=utf8mb4_general_ci
這樣寫不報錯,但是無法正常存儲。
另外,版本在5.1.13以后的支持自動檢測服務器設置,或者指定characterEncoding=utf-8。
但是我自己測試的結果就是 5.1.38 不寫connectionCollation的情況下,指定utf-8也報錯。
https://dev.mysql.com/doc/relnotes/connector-j/5.1/en/news-5-1-13.html
Connector/J now auto-detects servers configured with character_set_server=utf8mb4 or treats the Java encoding utf-8 passed using characterEncoding=... as utf8mb4 in the SET NAMES= calls it makes when establishing the connection. (Bug #54175)
即便寫了connectionCollation,Mysql也不能正確存儲。
mysql> 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 | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
| collation_connection | utf8mb4_general_ci |
| collation_database | utf8_general_ci |
| collation_server | utf8_bin |
+--------------------------+----------------------------+
11 rows in set (0.04 sec)
mysql> select hex(content) from send_message where id = 348;
+------------------------+
| hex(content) |
+------------------------+
| 3C703EF09F988A3C2F703E |
+------------------------+
1 row in set (0.04 sec)
#F09F988A//這個是emoji的hex值,通過navicat插入的。就可以。
mysql> select hex(content) from send_message where id = 349;
+------------------------+
| hex(content) |
+------------------------+
| 3C703E3F3F3F3F3C2F703E |
+------------------------+
1 row in set (0.04 sec)
#3F3F3F3F//這個是通過jdbc插入的,看樣子是無法正確存儲了。