Java → JDBC → MySQL 連線涉及三個關鍵字符集設置:
character_set_client:客戶端發送 SQL 的編碼character_set_connection:Server 解析 SQL 的編碼character_set_results:Server 返回結果集的編碼任一環節不一致 → 亂碼。
編輯 my.cnf / my.ini:
[client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4'
注意:[mysqld] 用 character-set-server,[client]/[mysql] 用 default-character-set,切勿混淆。
重啟驗證:
SHOW VARIABLES LIKE 'character%';
期望全部為 utf8mb4(除 character_set_filesystem=binary、character_set_system=utf8)。
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&autoReconnect=true&serverTimezone=Asia/Shanghai
useUnicode=true:啟用 Unicode 支持characterEncoding=utf8mb4:指定傳輸編碼connectionCollation=utf8mb4_unicode_ci:可選,指定連線校對規則HikariCP:
dataSource.setConnectionInitSql("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");
Druid:
dataSource.setConnectionInitSqls(Arrays.asList("SET NAMES utf8mb4"));
try (Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement()) {
stmt.execute("SET NAMES utf8mb4"); // 等同於設定 client/connection/results 三者
// 執行業務查詢
}
| 層級 | 檢查命令/配置 | 期望值 |
|---|---|---|
| Server 全域 | SHOW VARIABLES LIKE 'character_set%'; | utf8mb4 |
| Session | SHOW SESSION VARIABLES LIKE 'character_set%'; | utf8mb4 |
| 資料庫 | SHOW CREATE DATABASE db; | CHARSET=utf8mb4 |
| 表 | SHOW CREATE TABLE t; | CHARSET=utf8mb4 |
| JDBC URL | 檢查連接字符串 | characterEncoding=utf8mb4 |
| 應用日誌 | 啟用 SQL 日誌觀察實際發送字節 | 無亂碼 |
utf8 僅支援 BMP 平面(3 字節),**無法存儲 Emoji、生僻字**,必須用 utf8mb4SET NAMES utf8 在連接池複用場景下**不生效**(連接被複用前已設置),必須用 connectionInitSqlmy.cnf 中 [mysqld] 區段用 character-set-server 而非 default-character-setlatin1 存儲 UTF-8 數據(雙重編碼)需雙重轉換:CONVERT TO CHARACTER SET utf8mb4 前先 ALTER TABLE t CHANGE c c BLOB**全鏈路 utf8mb4** 是解決中文亂碼的唯一正解:
character-set-server=utf8mb4 + init_connectdefault-character-set=utf8mb4CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_cicharacterEncoding=utf8mb4 + 連接池 connectionInitSql一次配置,永久免疫亂碼。