Java MySQL 连接
JDBC(Java Database Connectivity)是 Java 访问数据库的统一标准:它定义连接、执行 SQL、处理结果等接口,由各数据库厂商提供驱动去实现。程序员只面向 JDBC API 编程,换数据库时基本不用改代码。MyBatis、Spring Data JPA 等框架底层都是 JDBC,本节内容是 Java 后端开发的地基。
JDBC 概念与驱动
- JDBC API:java.sql 包中的接口与类,与具体数据库无关。
- 驱动:厂商提供,负责把 JDBC 调用翻译成数据库协议,MySQL 驱动是 mysql-connector-j。
- Maven 引入 MySQL 8 驱动:
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
连接 URL 格式
DriverManager 通过 URL 定位数据库,格式为 jdbc:mysql://主机:端口/数据库名?参数,如:
jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
JDBC 六步流程
固定六步:①加载驱动 ②获取连接 ③创建 Statement ④执行 SQL ⑤处理结果 ⑥释放资源。完整示例需配置环境后运行(先建好 test 库):
import java.sql.*;
public class JdbcDemo {
public static void main(String[] args) throws Exception {
// ① 加载驱动(8.0 驱动可自动加载,显式写更清晰)
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/test?useSSL=false";
// ② 建立连接
try (Connection conn = DriverManager.getConnection(url, "root", "密码");
Statement st = conn.createStatement()) { // ③ 创建 Statement
// ④ 执行 DDL:建表
st.executeUpdate("CREATE TABLE IF NOT EXISTS user("
+ "id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), age INT)");
// ④ 执行 DML:增删改都用 executeUpdate,返回影响行数
int rows = st.executeUpdate("INSERT INTO user(name,age) VALUES('张三',25)");
System.out.println("插入行数:" + rows); // 输出:插入行数:1
// ④ 执行查询:executeQuery 返回 ResultSet
ResultSet rs = st.executeQuery("SELECT * FROM user");
// ⑤ 遍历结果集
while (rs.next()) {
System.out.println(rs.getInt("id") + " "
+ rs.getString("name") + " " + rs.getInt("age"));
}
} // ⑥ try-with-resources 自动释放连接等资源
}
}
getInt/getString 等 getter 既可传列名,也可传列序号(从 1 开始)。
PreparedStatement 防注入
用字符串拼接 SQL 存在注入风险,如用户输入 1' OR '1'='1 会改变查询语义。PreparedStatement 用 ? 占位符预编译,参数被当纯数据处理,从根上防住注入(片段需放进带连接的方法中运行):
String sql = "SELECT * FROM user WHERE name=? AND age=?";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "张三"); // 给第 1 个 ? 赋值
ps.setInt(2, 25); // 给第 2 个 ? 赋值
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("name"));
}
}
}
同一 SQL 还能预编译后反复执行、批量传参,性能优于 Statement。
事务 commit/rollback
多条写操作要求"同生共死"时开启事务:全部成功才 commit,任一步失败就 rollback(片段需放进带连接的方法中运行):
conn.setAutoCommit(false); // 关闭自动提交 = 开启事务
try {
st.executeUpdate("UPDATE account SET money=money-100 WHERE id=1");
st.executeUpdate("UPDATE account SET money=money+100 WHERE id=2");
conn.commit(); // 全部成功才提交
} catch (SQLException e) {
conn.rollback(); // 失败回滚,数据回到原样
throw e;
}
小结:JDBC 六步流程是数据库编程骨架;增删改用 executeUpdate、查询用 executeQuery + ResultSet 遍历;防注入优先 PreparedStatement,多步写操作务必用事务 commit/rollback 保证一致性。