Java 應用寫入中文到 MySQL 時拋出 Incorrect string value: '\\xE6\\x9B\\xB9\\xE5\\x86\\xAC...' for column 'realname',核心原因是**資料庫/表/欄位字元集非 utf8mb4**,無法存儲 4 位元組字符(含大部分中文、Emoji)。本文提供從驗證、修復到預防的完整解決路徑。
-- 檢查實例/庫/表/欄位字元集
SHOW VARIABLES LIKE 'character_set_%';
SHOW CREATE DATABASE your_db;
SHOW CREATE TABLE your_table;
SHOW FULL COLUMNS FROM your_table;
典型輸出(問題現場):
character_set_database = latin1DEFAULT CHARSET=latin1 (表級)COLLATE=latin1_swedish_ci (欄位級)latin1 單字節編碼,無法存儲中文(需 3 字節 UTF-8)或 Emoji(4 字節 utf8mb4)。
-- 1. 修改資料庫預設字元集 (僅影響後續新建表)
ALTER DATABASE your_db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 2. 修改現有表字元集 (轉換現有數據)
ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 3. 驗證
SHOW CREATE TABLE your_table;
-- 顯示: DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
⚠️ CONVERT TO 會**重建表、轉換現有數據**,大表會鎖表久,**必須低峰期操作、先備份**。
-- 僅轉換特定欄位 (不重建整表,速度快、風險低)
ALTER TABLE your_table MODIFY realname VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 或
ALTER TABLE your_table CHANGE realname realname VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
即使庫表是 utf8mb4,**連線字元集不正確也會亂碼**。
# JDBC URL (MySQL Connector/J 5.1+)
jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf8mb4&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
# 或連接後執行
SET NAMES utf8mb4; -- 等同於 SET character_set_client/connection/results = utf8mb4
# hibernate.cfg.xml / application.yml
hibernate:
connection:
CharSet: utf8mb4
characterEncoding: utf8mb4
useUnicode: true
dialect: org.hibernate.dialect.MySQL8Dialect
# 自動建表時指定字元集
hibernate.connection.provider_disables_autocommit: true
# 擴展 Dialect 自動加上 CHARSET (Hibernate 5+)
public class MySQL8Utf8mb4Dialect extends MySQL8Dialect {
@Override
public String getTableTypeString() {
return " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
}
}
-- 1. 直接插入測試
INSERT INTO your_table (realname) VALUES ('桑冬'), ('😀🎉');
SELECT realname, HEX(realname) FROM your_table;
-- HEX 應顯示 E6A1A5E586B5 (桑冬) 、F09F9880F09F8E89 (Emoji)
-- 2. Java 端測試
String sql = "INSERT INTO your_table (realname) VALUES (?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "測試中文😀");
ps.executeUpdate();
}
my.cnf 設定 character-set-server=utf8mb4、collation-server=utf8mb4_unicode_ciCREATE DATABASE ... DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE TABLE ... DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;characterEncoding=utf8mb4、useUnicode=trueIncorrect string value 本質是**字元集不匹配**。解決核心三步:**庫/表/欄位轉 utf8mb4 + 連線指定 utf8mb4 + 驅動升級**。測試環境用 CONVERT TO 徹底轉換;生產環境用 MODIFY COLUMN 精準修改熱點欄位。**新專案從 my.cnf 開始全鏈路 utf8mb4,根治亂碼。**