首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java JDBC 連接 MySQL 中文亂碼終極解決方案

     編輯:程式設計疑難解答

問題現象

  • 插入中文 → 資料庫顯示 `???` 或亂碼。
  • 查詢中文條件(`WHERE name='張三'`)→ 無結果。
  • 查詢結果讀取中文 → 正常顯示。
  • 資料庫、MyEclipse 均設為 GBK,連接串試過 `useUnicode=true&characterEncoding=UTF-8` 無效。

根本原因分析

編碼鏈路任一環節不一致即導致亂碼:

Java 字串(UTF-16) 
  → [JDBC 驅動編碼] → 
網路傳輸位元組流 
  → [MySQL 連接編碼 character_set_connection] → 
MySQL 內部操作 
  → [資料表/欄位編碼 character_set_column] → 
磁碟儲存

常見斷點:

  1. 連接串編碼與資料庫實際編碼不符:資料庫為 GBK,連接串指定 UTF-8 → 寫入時雙重編碼錯位。
  2. 資料表/欄位編碼未顯式指定:預設繼承資料庫/伺服器編碼,可能非預期值。
  3. JDBC 驅動版本過舊:早期版本對 `characterEncoding` 解析有 Bug。

標準化解決步驟

1. 統一全鏈路為 UTF-8(強烈推薦,現代標準)

-- 1. 資料庫/表/欄位全改 UTF-8 (utf8mb4 支援 Emoji)
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 或建表時指定
CREATE TABLE user (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 2. 連接串:明確指定 UTF-8,不依賴預設
jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
  • `utf8mb4` 是 MySQL 真正的 UTF-8(4 位元組),`utf8` 只有 3 位元組,不支援 Emoji/罕見字。
  • MySQL 8.0+ 預設即為 `utf8mb4`,5.7 需顯式指定。

2. 若必須維持 GBK 環境(舊系統)

-- 資料庫/表/欄位均為 GBK
CREATE DATABASE mydb CHARACTER SET gbk COLLATE gbk_chinese_ci;

-- 連接串對應 GBK
jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=gbk&serverTimezone=Asia/Shanghai
  • Java 源碼檔案編碼需與 IDE 設定一致(GBK 或 UTF-8),字串常量編碼由編譯器決定,JDBC 會按連接串編碼傳輸。

3. 驗證編碼生效

SHOW VARIABLES LIKE 'character_set_%';
SHOW CREATE TABLE user;

關鍵變數應顯示:

  • `character_set_client` = `utf8mb4` (或 gbk)
  • `character_set_connection` = `utf8mb4`
  • `character_set_results` = `utf8mb4`
  • `character_set_database` = `utf8mb4`
  • `character_set_server` = `utf8mb4`

避坑清單

錯誤做法正確做法
連接串用 `UTF-8`(大寫/中劃線)MySQL 識別名為 `utf8` 或 `utf8mb4`(無中劃線)
只改連接串,不改資料庫/表編碼全鏈路統一,缺一不可
用 `Statement` 拼接 SQL 字串用 `PreparedStatement` 參數化,避免編碼/注入雙重風險
MySQL 5.7 用 `utf8` 存 Emoji必須用 `utf8mb4`
驅動版本過舊 (5.1.30 以前)升級至 8.0.x (支援 MySQL 5.7/8.0)

總結

中文亂碼本質是編碼鏈路不一致。現代專案全鏈路統一 UTF-8 (utf8mb4) 是最省心、最通用、最面向未來的方案。老系統若無法遷移,則嚴格對齊 GBK 全鏈路。務必使用 `PreparedStatement` 參數化查詢,杜絕拼接 SQL 帶來的編碼與安全雙重隱患。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved