核心原因是字符编码在Java应用→JDBC→MySQL服务端→表/列存储全链路未对齐,必须统一为utf8mb4:MySQL端改配置并重启、JDBC URL加useUnicode=true&characterEncoding=utf8mb4、Java端显式设UTF-8编码、开发工具同步UTF-8。

Java 向 MySQL 插入中文时出现乱码或报错(如 ERROR 1406、???、问号、方块、截断等),核心原因是字符编码在“Java 应用 → JDBC 连接 → MySQL 服务端 → 表/列存储”这一链路中某处不一致。解决的关键不是单点修补,而是全链路对齐 UTF-8(推荐 utf8mb4)。
MySQL 服务端与数据库层级统一 utf8mb4
MySQL 默认字符集可能是 latin1 或旧版 utf8(实际只支持 BMP 字符,不支持 emoji 和部分生僻中文),必须升级为 utf8mb4:
- 登录 MySQL 执行:
SHOW VARIABLES LIKE 'character_set%';,重点检查character_set_server、collation_server - 修改配置文件(
my.cnf或my.ini),在[mysqld]下添加:[mysqld] default-character-set = utf8mb4 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
- 重启 MySQL 服务生效
- 对已有数据库执行:
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; - 对已有表执行:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
JDBC 连接字符串强制指定编码
仅改数据库不够,JDBC 驱动必须明确告诉 MySQL:“我传的是 utf8mb4 编码的数据”。连接 URL 中必须包含参数:
- 标准写法(JDBC 8.0+ 推荐):
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai -
useUnicode=true启用 Unicode 支持;characterEncoding=utf8mb4声明客户端传输编码;serverTimezone避免时区警告(非乱码主因但建议加上) - 避免使用
utf8(MySQL 的别名,实际是 utf8mb3),务必写utf8mb4 - 若用连接池(如 HikariCP、Druid),在连接池配置中设置
connectionInitSql为SET NAMES utf8mb4,确保每次连接初始化时生效
Java 端读写与 HTTP 层显式编码控制
Java 自身默认编码可能受系统影响(如 Windows 是 GBK),必须主动干预:
立即学习“Java免费学习笔记(深入)”;
- 读取请求参数前(Servlet 或 Filter 中):
request.setCharacterEncoding("UTF-8"); - 设置响应头(尤其返回 HTML 或 JSON):
response.setContentType("text/html; charset=UTF-8");response.setCharacterEncoding("UTF-8"); - 读取文件或流时,禁用默认构造:
✅ 正确:new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)
❌ 错误:new InputStreamReader(new FileInputStream(file))(依赖系统默认编码) - 启动 JVM 时加参数(治本):
-Dfile.encoding=UTF-8,让 String.getBytes() 等操作默认走 UTF-8
开发环境与工具链同步 UTF-8
IDE、终端、SQL 客户端的编码不一致,会导致“看着正常,存进去就乱”:
- IntelliJ IDEA:File → Settings → Editor → File Encodings → 全局、项目、默认编码设为 UTF-8,勾选 “Transparent native-to-ascii conversion”(对 properties 文件有效)
- Eclipse:Preferences → General → Workspace → Text file encoding → UTF-8
- Navicat / DBeaver:连接属性中设置「字符集」为 utf8mb4;查询窗口右下角确认当前编码显示为 utf8mb4
- Linux 终端:确保
locale输出含UTF-8;Windows 命令行不推荐直接插中文,改用 VS Code 内置终端或图形化工具


















