Java 通用数据库访问类(DBHelper)

Java 通用数据库访问类(DBHelper)

在 Java 项目中,数据库访问是最常见的操作之一。将连接、查询、更新、关闭等资源管理封装成一个工具类,可以避免到处写重复代码,也能确保连接及时释放。

单例模式

整个应用生命周期只需要一个数据库连接管理实例,采用单例模式实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DBHelper {
private static DBHelper connectionManager = null;
private static String databaseUser;
private static String databasePassword;
private static String databaseName;

public static DBHelper getInstance(String name, String user, String password) throws Exception {
if (user != null && !user.equals("")) {
databaseUser = user;
databasePassword = password;
databaseName = name;
}
if (connectionManager == null) {
connectionManager = new DBHelper();
}
return connectionManager;
}
}

连接与关闭

内部维护 ConnectionPreparedStatementResultSet 三个对象,对外暴露执行接口,关闭逻辑统一在 finally 中完成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private Connection getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/" + databaseName;
return DriverManager.getConnection(url, databaseUser, databasePassword);
} catch (Exception ex) {
System.err.println("获取数据库连接错误:" + ex.getMessage());
ex.printStackTrace();
}
return null;
}

public void closeDBResource() {
try {
if (rsSet != null) rsSet.close();
if (preStatement != null) preStatement.close();
if (dbConnection != null && !dbConnection.isClosed()) dbConnection.close();
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}

增删改查

执行更新(Insert / Update / Delete)

1
2
3
4
5
6
7
8
9
10
11
public int executeUpdate(String sql) {
try {
this.rsSet = null;
return getConnection().prepareStatement(sql).executeUpdate();
} catch (SQLException e) {
System.err.println("更新数据错误:" + e.getMessage());
return 0;
} finally {
closeDBResource();
}
}

执行查询(Select)

1
2
3
4
5
6
7
8
9
public ResultSet executeQuery(String sql) {
try {
this.rsSet = null;
this.rsSet = getConnection().prepareStatement(sql).executeQuery();
} catch (SQLException e) {
System.err.println("查询数据错误:" + e.getMessage());
}
return this.rsSet;
}

获取记录条数

1
2
3
4
5
6
7
8
9
10
11
12
public int getResultSetCount(String sql) {
int count = 0;
try {
this.rsSet = getConnection().prepareStatement(sql).executeQuery();
while (this.rsSet.next()) {
count++;
}
} catch (SQLException e) {
e.printStackTrace();
}
return count;
}

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
DBHelper db = DBHelper.getInstance("mydb", "root", "password");

// 查询
ResultSet rs = db.executeQuery("SELECT * FROM users WHERE age > 18");
while (rs.next()) {
System.out.println(rs.getString("name"));
}
db.closeDBResource();

// 更新
int rows = db.executeUpdate("UPDATE users SET status = 1 WHERE id = 5");
System.out.println("影响了 " + rows + " 行");

注意事项

  1. 驱动版本com.mysql.jdbc.Driver 在 MySQL Connector/J 8.0+ 中已弃用,应改为 com.mysql.cj.jdbc.Driver
  2. 连接泄漏executeQuery 返回的 ResultSet 需要调用方主动关闭,建议改为返回 List<Map> 等纯数据结构,由 DBHelper 内部关闭资源
  3. 线程安全:当前实现非线程安全,多线程环境下应使用 ThreadLocal<Connection>
  4. SQL 注入:当前直接拼接 SQL,生产环境应使用参数化查询(PreparedStatement.setXxx

小结

DBHelper 将 JDBC 的繁琐操作封装为简单的 executeUpdate / executeQuery / closeDBResource 三个调用,适合中小型项目快速上手。随着项目规模增长,建议逐步迁移到连接池(HikariCP、Druid)和 ORM 框架(MyBatis、JPA)。