核心概念
连接字符串是一个由特定格式的键值对组成的字符串,用于告诉 JDBC 驱动程序如何连接到数据库,它通常以 jdbc:mysql:// 开头。
主要组成部分
一个标准的 MySQL 连接字符串通常包含以下几个部分:
jdbc:mysql://[host][:port]/[database_name][?property1=value1&property2=value2]
1 基础部分 (必须)
jdbc:mysql://: 协议头,表示使用 MySQL 的 JDBC 驱动。host: 数据库服务器的地址,可以是 IP 地址(如168.1.100)或域名(如localhost或db.example.com)。port: 数据库服务器监听的端口号,MySQL 的默认端口是3306,如果使用默认端口,可以省略3306。database_name: 你要连接的具体数据库的名称。
示例:
- 连接到本地
3306端口的my_test_db数据库:jdbc:mysql://localhost/my_test_db - 连接到远程服务器
168.1.100的3306端口的production_db数据库:jdbc:mysql://192.168.1.100/production_db - 连接到远程服务器的非默认端口
3307:jdbc:mysql://192.168.1.100:3307/production_db
附加参数 (可选)
在基础部分的 之后,你可以添加一系列的参数,参数之间用 & 分隔,这些参数对于连接的性能、安全性和功能至关重要。
常用参数列表
| 参数 | 值 | 说明 | 推荐设置 |
|---|---|---|---|
user |
你的数据库用户名 | 用于身份验证。 | 必须 |
password |
你的数据库密码 | 用于身份验证。 | 必须 |
useSSL |
true / false |
是否使用 SSL/TLS 加密连接。重要:从 MySQL 5.7.11+ 和 8.0+ 开始,默认值变为 true,如果服务器未配置 SSL,连接会失败。 |
强烈推荐 false (开发环境) 或配置好 SSL 后使用 true (生产环境) |
serverTimezone |
时区字符串 (如 UTC, Asia/Shanghai) |
指定数据库服务器的时区,防止 java.sql.SQLException: The server time zone value '... 错误。 |
必须,尤其是在 Java 8+ 环境下 |
useUnicode |
true / false |
是否使用 Unicode 字符集。 | 推荐 true |
characterEncoding |
字符集 (如 UTF-8, GBK) |
指定连接使用的字符编码。重要:必须与数据库、表的字符集一致,否则会出现乱码。 | 推荐 UTF-8 |
allowPublicKeyRetrieval |
true / false |
当使用 caching_sha2_password 认证插件(MySQL 8+ 默认)时,如果密码未缓存,此参数允许客户端从服务器获取公钥以加密密码。 |
如果使用 MySQL 8+ 且遇到认证问题,尝试设置为 true |
useAffectedRows |
true / false |
true 时,executeUpdate() 的返回值只受影响的行数,不包括自动生成的值(如自增ID)。false(默认)则返回总数。 |
根据需求选择,通常保持默认 |
autoReconnect |
true / false |
当连接断开时,是否自动尝试重新连接。注意:此参数已被标记为过时,不推荐在生产环境中使用。 | 不推荐 |
failOverReadOnly |
true / false |
在主从切换后,失败的连接是否变为只读。 | 根据集群需求设置 |
不同 MySQL 版本的连接字符串示例
示例 1: MySQL 5.x (如 5.7)
这是比较经典的版本,使用 mysql-connector-java 5.x 驱动。
String jdbcUrl = "jdbc:mysql://localhost:3306/my_test_db" +
"?user=root" +
"&password=your_password" +
"&useSSL=false" + // 开发环境方便,生产环境建议配置好SSL
"&useUnicode=true" +
"&characterEncoding=UTF-8";
示例 2: MySQL 8.x (当前主流版本)
从 MySQL 8.0 开始,默认的认证插件从 mysql_native_password 变为 caching_sha2_password,这可能会导致旧版本的 JDBC 驱动(如 5.x)连接失败,新版本的驱动(8.x)已经很好地支持了它。
强烈建议使用与 MySQL 版本匹配的 Connector/J 驱动。
String jdbcUrl = "jdbc:mysql://localhost:3306/my_test_db" +
"?user=root" +
"&password=your_password" +
"&useSSL=false" + // 同上
"&serverTimezone=Asia/Shanghai" + // 解决时区问题
"&allowPublicKeyRetrieval=true" + // 解决caching_sha2_password认证问题
"&useUnicode=true" +
"&characterEncoding=UTF-8";
完整的 Java 连接代码示例
下面是一个完整的、使用 try-with-resources(推荐方式)来管理资源的 Java 类。
第一步:添加 JDBC 驱动依赖
如果你使用 Maven,在 pom.xml 中添加依赖:
<!-- For MySQL 5.x -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version> <!-- 使用你需要的版本 -->
</dependency>
<!-- For MySQL 8.x (推荐) -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version> <!-- 使用你需要的版本 -->
</dependency>
如果你使用 Gradle,在 build.gradle 中添加:
// For MySQL 8.x (推荐) implementation 'com.mysql:mysql-connector-j:8.0.33'
第二步:编写 Java 代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
public class MysqlJdbcExample {
// --- 请根据你的环境修改以下信息 ---
private static final String DB_URL = "jdbc:mysql://localhost:3306/my_test_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
private static final String USER = "root";
private static final String PASS = "your_password";
// ---------------------------------
public static void main(String[] args) {
// try-with-resources 语句会自动关闭 Connection, Statement, 和 ResultSet
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 'Hello, MySQL!' as message")) {
// 检查连接是否成功
if (conn != null) {
System.out.println("Connection to MySQL database successful!");
}
// 处理查询结果
while (rs.next()) {
// 列名是 "message"
String message = rs.getString("message");
System.out.println("Query Result: " + message);
}
} catch (SQLException e) {
System.err.println("Connection Failed! Check output console");
e.printStackTrace();
}
}
}
常见问题与最佳实践
-
时区错误
The server time zone value ...- 原因:JDBC 4.2 (Java 8) 驱动需要显式指定服务器时区。
- 解决:在连接字符串中添加
&serverTimezone=Asia/Shanghai(或你的服务器所在时区)。
-
认证插件不兼容
Public key retrieval is not allowed- 原因:MySQL 8+ 默认使用
caching_sha2_password,但 JDBC 驱动无法安全地传输密码。 - 解决:
a. 推荐:升级 JDBC 驱动到 8.x 版本。
b. 临时方案:在连接字符串中添加
&allowPublicKeyRetrieval=true。 c. 最佳实践:在 MySQL 服务器上将用户认证插件改回mysql_native_password:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';。
- 原因:MySQL 8+ 默认使用
-
SSL 连接问题
- 原因:新版 MySQL 默认要求 SSL,但开发环境可能没配置。
- 解决:在连接字符串中添加
&useSSL=false。注意:这仅适用于开发或内部网络,生产环境应配置 SSL。
-
乱码问题
- 原因:客户端、连接、数据库的字符集不一致。
- 解决:确保数据库、表、字段都使用
utf8mb4字符集,并在连接字符串中指定&useUnicode=true&characterEncoding=UTF-8。
-
不要将密码硬编码在代码中
- 最佳实践:将数据库连接信息(URL, 用户名, 密码)存储在配置文件(如
config.properties)或环境变量中,而不是直接写在 Java 代码里。
- 最佳实践:将数据库连接信息(URL, 用户名, 密码)存储在配置文件(如
希望这份详细的指南能帮助你成功连接到 MySQL 数据库!
