中文亂碼本質是編碼不一致:資料庫、連線、JVM、HTML 頁面四端編碼任一不匹配即產生亂碼。本文以 Hibernate + MySQL 為例,建立「三層一致性」配置清單,一次解決存儲、讀取、顯示全鏈路亂碼。
| 層級 | 配置位置 | 關鍵設定 | 推薦值 |
|---|---|---|---|
| 1. 資料庫/資料表 | DDL / my.cnf |
CHARACTER SET utf8mb4COLLATE utf8mb4_unicode_ci |
utf8mb4 (支援 Emoji) |
| 2. JDBC 連線 | Hibernate 配置 / 連線字串 | characterEncoding=utf8useUnicode=true |
utf8 (驅動別名對應 utf8mb4) |
| 3. Hibernate 映射 | hibernate.cfg.xml / 註解 |
hibernate.connection.characterEncoding |
utf8 |
-- 建庫指定字符集
CREATE DATABASE mydb
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 建表指定字符集 (若庫已設定可省略)
CREATE TABLE user (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改現有表
ALTER TABLE user
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
關鍵:utf8mb4 為真正 UTF-8 (4 bytes),utf8 僅 3 bytes 不支援 Emoji/生僻字。
jdbc:mysql://localhost:3306/mydb?
useUnicode=true&
characterEncoding=utf8&
serverTimezone=Asia/Taipei&
useSSL=false
characterEncoding=utf8:驅動內部會映射到 SET NAMES utf8mb4useUnicode 預設 true 可省略hibernate.cfg.xml)<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<!-- 明確指定連線字符集 (雙重保險) -->
<property name="hibernate.connection.characterEncoding">utf8</property>
<property name="hibernate.connection.useUnicode">true</property>
<!-- 方言匹配 MySQL 版本 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
application.yml 現代寫法spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Taipei
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
| 項目 | Linux (生產) | Windows (開發) |
|---|---|---|
| OS 預設編碼 | UTF-8 | GBK/CP950 (繁中) |
| JVM file.encoding | UTF-8 | 常為 GBK/Big5 |
| 建議 JVM 參數 | -Dfile.encoding=UTF-8 | 必加 -Dfile.encoding=UTF-8 |
| Tomcat server.xml | URIEncoding="UTF-8" | URIEncoding="UTF-8" |
SHOW VARIABLES LIKE 'character_set%'; 確認資料庫/表/連線皆為 utf8mb4SELECT HEX(name) FROM user WHERE id=1; 查看實際儲存位元組 (E4 B8 AD = "中")Content-Type: text/html; charset=UTF-8System.getProperty("file.encoding")**「資料庫 utf8mb4、連線 utf8、JVM UTF-8、頁面 UTF-8」四端統一**,亂碼即消失。新專案直接上 utf8mb4,避免日後遷移痛。