本质是字符编码链路断裂,须确保Java应用、JDBC驱动、数据库服务端、库表结构四层均统一使用utf8mb4,且JVM默认编码为UTF-8,缺一不可。

Java 通过 JDBC 连接数据库时出现中文乱码,本质是字符编码链路断裂——从 Java 应用、JDBC 驱动、网络传输到数据库服务端,任一环节未对齐 UTF-8,就会解码失败。解决不是加一个参数,而是确保“三层一致”:连接参数、数据库服务端配置、库表结构都使用 utf8mb4(非 utf8),且 Java 运行环境本身也默认 UTF-8。
JDBC 连接字符串必须显式启用 UTF-8 解码
这是最直接、最容易遗漏的一步。仅靠驱动自动推断往往失效:
- MySQL(推荐):
jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai
注意:useUnicode=true和characterEncoding=utf8mb4缺一不可;utf8在 MySQL 8+ 中实际对应 utf8mb3,不支持 emoji,易出问题。 - PostgreSQL:
jdbc:postgresql://localhost:5432/mydb?stringtype=unspecified
无需charset参数,但需确保服务端 locale 为 UTF-8(如zh_CN.UTF-8)。 - Oracle:
jdbc:oracle:thin:@//host:1521/orcl
URL 中禁用characterEncoding和useUnicode(ojdbc8+ 完全不识别,加了反而报错);改用 JVM 启动参数:-Dfile.encoding=UTF-8 -Doracle.jdbc.defaultNChar=true。
数据库服务端必须设为 utf8mb4
连接参数再正确,若服务端默认用 latin1 处理请求,照样乱码:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- MySQL:在
my.cnf的[mysqld]段添加:character_set_server = utf8mb4collation_server = utf8mb4_unicode_ci
重启后执行SHOW VARIABLES LIKE 'character\_set\_%';,确认所有关键项(client/connection/server/results)均为utf8mb4。 - PostgreSQL:检查
SHOW server_encoding;必须返回UTF8;SHOW lc_messages;建议为zh_CN.UTF-8(避免错误信息乱码)。 - Oracle:依赖数据库字符集(如 AL32UTF8)和 NLS 设置,JVM 的
file.encoding必须与之匹配。
建库建表必须显式指定 utf8mb4
即使连接和服务端都对了,建库建表时若没声明字符集,仍会继承旧配置(可能还是 latin1):
立即学习“Java免费学习笔记(深入)”;
- 创建数据库:
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 创建表:
CREATE TABLE t1 (name VARCHAR(100)) CHARSET=utf8mb4; - 已有表转换:
ALTER TABLE t1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Java 代码里别做多余编码转换
连接和库表都设对了,但写法错误仍会导致二次乱码:
- 插入前不要手动调用:
new String(str.getBytes("GBK"), "UTF-8")—— 这是典型错误,会把本已正确的 UTF-8 字节流误当 GBK 解码再重编码。 - 读取 ResultSet 时,直接用
rs.getString("col")即可,JDBC 驱动已按连接参数完成解码。 - Maven 项目务必在
pom.xml中声明源码编码:<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - JVM 启动参数加上:
-Dfile.encoding=UTF-8,并验证:System.getProperty("file.encoding")输出为UTF-8。

















