早期 Java + MySQL(Connector/J 3.x/5.0 時代)中文亂碼高發,許多開發者採用「寫入不轉碼、讀出轉 ISO-8859-1」的 Bean 封裝大法。本文剖析該方案的本質缺陷,給出現代 JDBC 連接參數一站式解決方案。
// 工具類:嘗試將字符串按 ISO-8859-1 重新解碼
public class Format2Chinese {
public String format2ISO8859(String str) {
if (str == null || str.trim().isEmpty()) return "";
try {
// 錯誤示範:getBytes("ISO-8859-1") 再用平台默認編碼構造 String
// 正確應為:new String(str.getBytes("ISO-8859-1"), "GBK/UTF-8")
return new String(str.getBytes("ISO-8859-1"));
} catch (Exception e) { e.printStackTrace(); return str; }
}
}
// Bean 中調用
public class LeaveMsg {
private String msg;
private boolean format = false;
private Format2Chinese fn = new Format2Chinese();
public void setMsg(String msg) {
this.msg = format ? fn.format2ISO8859(msg) : msg;
}
// getter...
}
str.getBytes("ISO-8859-1") 按單字節截斷多字節字符,再用平台默認編碼(GBK/UTF-8)構造 String,產生的字符串已不可逆損壞。format 旗標,維護成本極高。jdbc:mysql://host:3306/dbname?
useUnicode=true&
characterEncoding=utf8&
connectionCollation=utf8mb4_general_ci&
serverTimezone=Asia/Shanghai
useUnicode=true:啟用 Unicode 支持。characterEncoding=utf8:客戶端/服務端通信編碼(MySQL 端對應 utf8mb4)。connectionCollation:連接校對規則,避免隱式轉換。jdbc:mysql://host:3306/dbname?serverTimezone=Asia/Shanghai
characterEncoding=UTF-8、useUnicode=true、connectionCollation=utf8mb4_0900_ai_ci,**通常無需額外參數**。[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_0900_ai_ci
# 或 utf8mb4_general_ci(舊版兼容)
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
SHOW VARIABLES LIKE 'character_set%'; → 除 filesystem 外全為 utf8mb4。SHOW VARIABLES LIKE 'collation%'; → 全為 utf8mb4_0900_ai_ci 或 utf8mb4_general_ci。getBytes/ new String 轉碼。Format2Chinese 調用。utf8mb4(ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4)。**結論**:拋棄 Bean 級轉碼大法,擁抱 JDBC 連接參數 + 服務端統一 utf8mb4,是解決 Java-MySQL 中文亂碼的**唯一正確、可維護、高性能**路徑。