Java作为企业级开发的主流语言,与MySQL数据库的交互是后端开发的核心技能之一,通过JDBC(Java Database Connectivity)规范,Java程序可以统一操作各种关系型数据库,而MySQL凭借其开源、高效的特点,成为众多项目的首选,本文将从基础连接、SQL执行、批处理、事务管理、连接池优化等维度,系统介绍Java中执行MySQL语句的方法与最佳实践。

JDBC基础连接与核心对象
在Java中操作MySQL,首先需要建立数据库连接,JDBC的核心流程包括加载驱动、获取连接、创建执行对象和释放资源。
- 加载驱动:MySQL 8.0+版本使用
com.mysql.cj.jdbc.Driver,通过Class.forName()加载驱动类(JDBC 4.0后可省略此步骤,但显式加载更明确)。 - 获取连接:使用
DriverManager.getConnection()方法,传入数据库URL、用户名和密码,URL格式为jdbc:mysql://主机名:端口/数据库名?参数,例如jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC。 - 核心对象:
Connection代表数据库连接,Statement用于执行SQL,PreparedStatement是预编译的Statement(更安全高效),ResultSet存储查询结果。
// 示例:基础连接
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test", "root", "password");
SQL执行的核心方法:Statement与PreparedStatement
根据SQL类型和安全性需求,可选择不同的执行对象。
- Statement:适用于静态SQL,直接拼接字符串执行,但存在SQL注入风险,例如
String sql = "SELECT * FROM users WHERE name = '" + username + "'";中,恶意用户可通过输入' OR '1'='1绕过验证。 - PreparedStatement:通过占位符预编译SQL,再绑定参数,有效防止SQL注入,且重复执行时性能更优,适用于动态SQL场景,如查询、更新、删除操作。
// PreparedStatement示例:插入数据 String sql = "INSERT INTO users(name, age) VALUES(?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, "张三"); // 绑定第一个参数 pstmt.setInt(2, 25); // 绑定第二个参数 int rows = pstmt.executeUpdate(); // 执行增删改,返回受影响行数
批处理操作提升效率
当需要执行大量重复SQL(如批量插入、更新)时,批处理可显著减少网络开销和数据库交互次数。

- Statement批处理:通过
addBatch()添加SQL,executeBatch()执行,最后clearBatch()清空。 - PreparedStatement批处理:更高效,适合参数化SQL的批量操作,需注意分批提交(如每1000条提交一次),避免内存溢出。
// PreparedStatement批处理示例
String sql = "INSERT INTO users(name, age) VALUES(?, ?)";
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < 1000; i++) {
pstmt.setString(1, "用户" + i);
pstmt.setInt(2, 20 + i % 10);
pstmt.addBatch(); // 添加到批处理
if (i % 100 == 0) pstmt.executeBatch(); // 分批执行
}
pstmt.executeBatch(); // 执行剩余批处理
事务管理确保数据一致性
事务是数据库操作的最小执行单元,具有ACID(原子性、一致性、隔离性、持久性)特性,JDBC通过Connection控制事务:
- 关闭自动提交:
conn.setAutoCommit(false),将多条SQL绑定为一个事务。 - 提交或回滚:执行成功时
conn.commit(),失败时conn.rollback()。 - 设置隔离级别:通过
conn.setTransactionIsolation()指定,如READ_COMMITTED(读已提交)、SERIALIZABLE(可串行化),避免脏读、不可重复读等问题。
// 事务示例:转账操作
try {
conn.setAutoCommit(false);
// 扣款
pstmt = conn.prepareStatement("UPDATE accounts SET balance = balance - ? WHERE id = ?");
pstmt.setDouble(1, 100.0);
pstmt.setInt(2, 1);
pstmt.executeUpdate();
// 存款
pstmt = conn.prepareStatement("UPDATE accounts SET balance = balance + ? WHERE id = ?");
pstmt.setDouble(1, 100.0);
pstmt.setInt(2, 2);
pstmt.executeUpdate();
conn.commit(); // 提交事务
} catch (Exception e) {
conn.rollback(); // 回滚事务
e.printStackTrace();
}
连接池优化性能
直接使用DriverManager获取连接效率低,频繁创建和销毁连接会消耗大量资源,连接池(如HikariCP、Druid)通过复用连接提升性能,是生产环境的标配。
以HikariCP为例:
- 引入依赖:在Maven项目中添加
com.zaxxer:HikariCP。 - 配置连接池:设置最大连接数、连接超时时间、空闲连接回收等参数。
- 获取连接:通过连接池对象获取
Connection,使用后无需手动关闭(连接池会回收)。
// HikariCP示例
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/test");
config.setUsername("root");
config.setPassword("password");
config.setMaximumPoolSize(10); // 最大连接数
HikariDataSource ds = new HikariDataSource(config);
Connection conn = ds.getConnection(); // 从连接池获取连接
常见问题与最佳实践
- 资源释放:使用
try-with-resources(JDK 7+)自动关闭Connection、Statement、ResultSet,避免资源泄漏。try (Connection conn = ds.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { // 执行SQL } catch (SQLException e) { e.printStackTrace(); } - SQL注入防护:始终使用
PreparedStatement,避免字符串拼接SQL。 - 异常处理:捕获
SQLException,记录日志并回滚事务,避免异常导致数据不一致。 - 性能优化:合理设置连接池大小(通常为
CPU核心数*2+1),使用索引优化查询,避免N+1查询问题。
Java执行MySQL语句的核心是掌握JDBC基础对象、安全高效的SQL执行方式、事务与连接池管理,通过合理选择Statement或PreparedStatement,利用批处理和事务特性,并结合连接池优化,可以构建高性能、高可靠的数据库交互程序,在实际开发中,还需结合具体业务场景,遵循最佳实践,确保代码的健壮性与可维护性。














