Java数据库连接(JDBC)是Java语言与数据库交互的核心技术,它为开发者提供了一套标准API,使得Java程序能够通过各种数据库驱动程序连接到不同的数据库管理系统,并执行SQL语句、处理结果集,掌握JDBC的正确使用方法,是Java后端开发的基础技能,本文将从环境准备、连接数据库、执行SQL、处理结果到资源释放等环节,系统介绍JDBC的使用流程和最佳实践。

环境准备与驱动加载
在使用JDBC之前,需要完成两项关键准备工作:获取数据库驱动程序和加载驱动,数据库驱动是JDBC与特定数据库通信的桥梁,不同的数据库(如MySQL、Oracle、PostgreSQL)都有各自对应的驱动jar包,MySQL 8.x版本的驱动为mysql-connector-java-8.x.x.jar,开发者需要将驱动jar包添加到项目的类路径中(在Maven或Gradle项目中可通过依赖管理工具自动引入)。
加载驱动是JDBC工作的第一步,通过调用Class.forName()方法显式加载驱动类,这一步会初始化驱动管理器(DriverManager),注册驱动程序实例,以MySQL为例,加载驱动的代码为Class.forName("com.mysql.cj.jdbc.Driver"),注意,从JDBC 4.0开始,驱动实现会自动通过META-INF/services/java.sql.Driver文件注册,因此在某些情况下可以省略显式加载步骤,但显式加载仍是确保兼容性的可靠做法。
建立数据库连接
连接数据库是JDBC操作的核心环节,主要通过DriverManager.getConnection()方法实现,该方法需要三个参数:数据库URL、用户名和密码,数据库URL的格式因数据库而异,以MySQL为例,标准格式为jdbc:mysql://[hostname]:[port]/[database]?[properties],其中hostname为数据库服务器地址(本地可用localhost),port为端口号(MySQL默认为3306),database为数据库名称,properties为可选的连接属性(如useSSL=false、serverTimezone=UTC等)。
建立连接时,建议使用try-with-resources语句自动管理Connection对象,确保连接在使用完毕后能被正确关闭。
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// 连接成功,执行数据库操作
} catch (SQLException e) {
e.printStackTrace();
}
如果连接失败,通常会抛出SQLException,开发者需要捕获异常并处理,例如打印错误日志或提示用户。

创建执行语句对象
成功获取Connection对象后,需要通过它创建Statement或其子接口PreparedStatement来执行SQL语句。Statement用于执行静态SQL语句,而PreparedStatement用于执行预编译SQL语句,后者能有效防止SQL注入攻击,且在多次执行相同SQL时性能更优。
创建Statement对象直接通过conn.createStatement()实现,而PreparedStatement则需要通过conn.prepareStatement(sql)传入SQL模板(包含占位符)。
String sql = "INSERT INTO users (username, password) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, "john_doe");
pstmt.setString(2, "secure_password");
// 执行SQL
}
在开发中,应优先选择PreparedStatement,特别是在涉及用户输入的场景下,以避免SQL注入风险,对于批量操作或存储过程调用,还可使用CallableStatement接口。
执行SQL语句并处理结果集
根据SQL语句的类型(查询、更新、删除等),需要选择不同的执行方法,对于查询操作(SELECT),应使用executeQuery()方法,该方法返回一个ResultSet对象,包含查询结果的结果集;对于更新操作(INSERT、UPDATE、DELETE)或无返回值的SQL,则使用executeUpdate()方法,返回受影响的行数。
处理ResultSet时,同样建议使用try-with-resources确保结果集自动关闭,遍历结果集通过next()方法实现,该方法将光标移动到下一行,如果存在下一行则返回true。

String sql = "SELECT id, username FROM users";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
System.out.println("ID: " + id + ", Username: " + username);
}
}
通过getXxx()方法(如getString()、getInt()、getDate()等)获取列值,可根据列名或列索引(从1开始)指定列,对于复杂查询,还可使用ResultSetMetaData获取列的元数据信息,如列名、数据类型等。
事务管理与资源释放
JDBC默认采用自动提交模式(autoCommit=true),每条SQL语句执行后会立即提交,但在需要保证数据一致性的场景(如银行转账),需要手动管理事务:通过conn.setAutoCommit(false)关闭自动提交,在所有SQL执行成功后调用conn.commit()提交事务,若发生异常则调用conn.rollback()回滚事务。
try {
conn.setAutoCommit(false);
// 执行多条SQL
stmt.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
stmt.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
conn.setAutoCommit(true); // 恢复自动提交模式
}
资源释放是JDBC开发中不可忽视的一环。Connection、Statement、ResultSet等资源均属于JDBC资源,占用数据库连接和内存,若未及时释放可能导致资源泄漏,通过try-with-resources语句,可以确保这些对象在代码块执行完毕后自动调用close()方法,无需手动关闭。
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
// 使用资源
} // 自动关闭资源
最佳实践与注意事项
- 使用连接池:直接使用
DriverManager获取连接性能较低,生产环境中应使用连接池(如HikariCP、Druid)管理数据库连接,避免频繁创建和销毁连接。 - 防止SQL注入:始终使用
PreparedStatement处理用户输入,拼接SQL语句存在严重的安全风险。 - 合理设置事务隔离级别:根据业务需求设置适当的事务隔离级别(如
READ_COMMITTED、SERIALIZABLE),避免脏读、不可重复读等问题。 - 处理大结果集:对于大结果集,可通过
Statement.setFetchSize()设置获取大小,或使用ResultSet.TYPE_FORWARD_ONLY和ResultSet.FETCH_TYPE_FORWARD_ONLY优化内存使用。 - 日志与异常处理:记录SQL执行日志和异常信息,便于排查问题;避免捕获异常后仅打印堆栈而不处理,应根据业务场景进行重试或回滚。
通过以上步骤和注意事项,开发者可以高效、安全地使用JDBC进行数据库操作,掌握JDBC不仅是Java开发的基础,也是理解ORM框架(如Hibernate、MyBatis)工作原理的前提,在实际开发中,结合具体业务场景灵活运用JDBC技术,能够构建出稳定、高效的数据库应用系统。


















