中文亂碼是 Java/Hibernate 連接 MySQL 時的經典痛點。本文針對「兩頭 UTF-8 正常、中間連線亂碼」的核心矛盾,給出 JDBC URL 參數標準配置與 XML 轉義最佳實踐。
System.out.println("中文") → 控制台正常顯示根因:JDBC 連線未指定字元集,驅動程式預設使用 latin1 (ISO-8859-1) 傳輸,導致 UTF-8 位元組流被錯誤解碼。
jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8
useUnicode=true:啟用 Unicode 支援,告訴驅動程式使用字元集轉換characterEncoding=utf8:指定傳輸編碼為 UTF-8(MySQL 內部為 utf8mb3,8.0+ 建議 utf8mb4)<property name="connection.url">
jdbc:mysql://localhost:3306/tablename?useUnicode=true&characterEncoding=utf8
</property>
XML 解析器會將 & 解析為實體引用開頭,導致參數解析失敗。
<property name="connection.url">
jdbc:mysql://localhost:3306/tablename?useUnicode=true&characterEncoding=utf8
</property>
<property name="connection.url">
<![CDATA[
jdbc:mysql://localhost:3306/tablename?useUnicode=true&characterEncoding=utf8
]]>
</property>
內容不被 XML 解析器處理,原樣輸出,完美解決特殊字元問題。
jdbc:mysql://localhost:3306/your_database?
useUnicode=true&
characterEncoding=utf8mb4&
serverTimezone=Asia/Taipei&
useSSL=false&
allowPublicKeyRetrieval=true
utf8mb4:真正的 UTF-8,支援 4 位元組字符(Emoji、生僻字)serverTimezone:避免時區解析警告,必須指定 IANA 時區 IDuseSSL=false:開發環境關閉 SSL 簡化配置allowPublicKeyRetrieval=true:配合 caching_sha2_password 插件允許公開金鑰獲取[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
驗證:SHOW VARIABLES LIKE 'character_set%'; 所有 *_server/*_database/*_connection 均為 utf8mb4。
<property name="hibernate.connection.CharSet">utf8mb4</property>
<property name="hibernate.connection.characterEncoding">utf8mb4</property>
<property name="hibernate.connection.useUnicode">true</property>
CREATE DATABASE db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE TABLE t (...) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;col VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_cicharacterEncoding=utf8mb4character_set_server=utf8mb4Content-Type: text/html; charset=UTF-8中文亂碼本質是「編碼鏈路任一環節不一致」。建立「全鏈路 UTF-8mb4」標準化配置清單,納入專案初始化檢查項,從根源杜絕亂碼問題。