本文目录导读:

在Java中封装JDBC工具类的核心目的是减少重复代码、统一资源管理、提高可维护性,以下是业界常用且稳健的封装方案,包含完整代码和最佳实践。
基础版JDBC工具类 (最常用)
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
// 静态代码块:类加载时执行一次,读取配置文件
static {
try {
// 方式1:读取classpath下的jdbc.properties
InputStream is = JDBCUtils.class.getClassLoader()
.getResourceAsStream("db.properties");
Properties props = new Properties();
props.load(is);
driver = props.getProperty("jdbc.driver");
url = props.getProperty("jdbc.url");
username = props.getProperty("jdbc.username");
password = props.getProperty("jdbc.password");
// 注册驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("数据库连接失败!", e);
}
}
/**
* 获取数据库连接
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
/**
* 释放资源(用于查询操作)
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
close(conn, stmt);
}
/**
* 释放资源(用于增删改操作,无结果集)
*/
public static void close(Connection conn, Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
对应配置文件 db.properties (放在src根目录):
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC jdbc.username=root jdbc.password=123456
增强版:支持事务管理
import java.sql.Connection;
import java.sql.SQLException;
/**
* 增强版:支持手动事务控制
*/
public class JDBCUtilsEnhanced {
// 使用ThreadLocal保证每个线程独立Connection
private static ThreadLocal<Connection> tl = new ThreadLocal<>();
/**
* 获取当前线程的Connection(支持事务)
*/
public static Connection getCurrentConnection() throws SQLException {
Connection conn = tl.get();
if (conn == null) {
conn = JDBCUtils.getConnection();
tl.set(conn);
}
return conn;
}
/**
* 开启事务
*/
public static void beginTransaction() throws SQLException {
Connection conn = getCurrentConnection();
conn.setAutoCommit(false);
}
/**
* 提交事务
*/
public static void commitTransaction() throws SQLException {
Connection conn = getCurrentConnection();
if (conn != null) {
conn.commit();
conn.setAutoCommit(true); // 恢复自动提交
}
}
/**
* 回滚事务
*/
public static void rollbackTransaction() throws SQLException {
Connection conn = getCurrentConnection();
if (conn != null) {
conn.rollback();
conn.setAutoCommit(true);
}
}
/**
* 清除ThreadLocal中的连接(重要!)
*/
public static void closeConnection() throws SQLException {
Connection conn = tl.get();
if (conn != null) {
conn.close();
tl.remove(); // 必须清除,防止内存泄漏
}
}
}
使用示例
1 查询操作
public List<User> findAllUsers() {
String sql = "SELECT * FROM users";
List<User> list = new ArrayList<>();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
list.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 注意释放顺序:ResultSet -> Statement -> Connection
JDBCUtils.close(conn, pstmt, rs);
}
return list;
}
2 事务操作
public void transferMoney(int fromId, int toId, double amount) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
// 1. 获取连接并开启事务
conn = JDBCUtilsEnhanced.getCurrentConnection();
JDBCUtilsEnhanced.beginTransaction();
// 2. 执行两个更新操作
String sql1 = "UPDATE account SET money = money - ? WHERE id = ?";
pstmt1 = conn.prepareStatement(sql1);
pstmt1.setDouble(1, amount);
pstmt1.setInt(2, fromId);
pstmt1.executeUpdate();
// 模拟异常
// int i = 1/0;
String sql2 = "UPDATE account SET money = money + ? WHERE id = ?";
pstmt2 = conn.prepareStatement(sql2);
pstmt2.setDouble(1, amount);
pstmt2.setInt(2, toId);
pstmt2.executeUpdate();
// 3. 提交事务
JDBCUtilsEnhanced.commitTransaction();
} catch (SQLException e) {
try {
JDBCUtilsEnhanced.rollbackTransaction();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
// 释放资源
JDBCUtils.close(conn, pstmt1);
JDBCUtils.close(null, pstmt2);
// 清除ThreadLocal
try {
JDBCUtilsEnhanced.closeConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
最佳实践总结
| 要点 | 说明 |
|---|---|
| 配置文件 | 使用 .properties 或 .yml 避免硬编码 |
| 驱动注册 | 静态代码块执行一次,避免重复注册 |
| 资源释放 | 遵循 ResultSet → Statement → Connection 顺序 |
| 关闭判断 | 每个资源关闭前判断 null,防止空指针 |
| ThreadLocal | 事务场景必备,确保同一线程共用连接 |
| finally块 | 确保资源在任何情况下都被释放 |
| 异常处理 | 使用 printStackTrace() 或日志记录,避免吞异常 |
进阶:使用连接池优化
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.util.Properties;
public class JDBCPoolUtils {
private static DataSource dataSource;
static {
try {
Properties props = new Properties();
props.load(JDBCPoolUtils.class.getClassLoader()
.getResourceAsStream("druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(props);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
// 其他方法同JDBCUtils(close方法不需要关闭真正的连接,而是归还到连接池)
}
druid.properties:
driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/mydb username=root password=123456 initialSize=5 maxActive=10
这样封装后,你的JDBC代码将具备可配置性、易维护性、健壮性,是生产环境的标配做法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播