萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

Java 存入中文到 MySQL 報 Incorrect string value 完美解決方案

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 = latin1
  • DEFAULT CHARSET=latin1 (表級)
  • COLLATE=latin1_swedish_ci (欄位級)

latin1 單字節編碼,無法存儲中文(需 3 字節 UTF-8)或 Emoji(4 字節 utf8mb4)。

二、分場景解決方案

方案 A:測試環境/數據可重建 —— 一勞永逸修改庫/表字元集

-- 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 會**重建表、轉換現有數據**,大表會鎖表久,**必須低峰期操作、先備份**。

方案 B:生產環境/數據不可遺失 —— 僅修改需寫入中文的欄位

-- 僅轉換特定欄位 (不重建整表,速度快、風險低)
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;

方案 C:連線層面指定字元集(應用端必做)

即使庫表是 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

方案 D:Hibernate / JPA 配置

# 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();
}

四、預防清單(新專案必做)

  1. 實例級: my.cnf 設定 character-set-server=utf8mb4、collation-server=utf8mb4_unicode_ci
  2. 庫級: CREATE DATABASE ... DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  3. 表級: CREATE TABLE ... DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  4. 連線級: JDBC URL 含 characterEncoding=utf8mb4、useUnicode=true
  5. 驅動版本: MySQL Connector/J 8.0+ (支援 utf8mb4 原生)

五、總結

Incorrect string value 本質是**字元集不匹配**。解決核心三步:**庫/表/欄位轉 utf8mb4 + 連線指定 utf8mb4 + 驅動升級**。測試環境用 CONVERT TO 徹底轉換;生產環境用 MODIFY COLUMN 精準修改熱點欄位。**新專案從 my.cnf 開始全鏈路 utf8mb4,根治亂碼。**

copyright © 萬盛學電腦網 all rights reserved