Java中通过抽象类实现通用数据库访问模板,核心是模板方法模式:抽象类BaseDao封装连接获取、事务控制、资源关闭等固定流程,子类只需实现buildQuerySql、buildQueryParams、mapResultSet等可变逻辑。

Java 中通过抽象类实现通用数据库访问模板,核心是用 模板方法模式(Template Method Pattern) 将数据库操作的固定流程(如获取连接、开启事务、执行 SQL、处理结果、关闭资源)封装在抽象类中,而把可变部分(如 SQL 语句、参数设置、结果映射)留给子类实现。
定义抽象数据库模板类
创建一个抽象类(例如 BaseDao<T>),封装共性逻辑:
- 统一管理
Connection、PreparedStatement、ResultSet的获取与释放 - 提供事务控制钩子(如
beginTransaction()、commit()、rollback()) - 声明抽象方法,由子类具体实现关键行为
示例:
public abstract class BaseDao<T> {
protected DataSource dataSource;
public BaseDao(DataSource dataSource) {
this.dataSource = dataSource;
}
// 模板方法:对外提供的统一入口
public List<T> findAll() {
String sql = buildQuerySql();
List<Object> params = buildQueryParams();
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
setParameters(ps, params);
ResultSet rs = ps.executeQuery();
return mapResultSet(rs);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// 以下为子类必须实现的方法
protected abstract String buildQuerySql();
protected abstract List<Object> buildQueryParams();
protected abstract List<T> mapResultSet(ResultSet rs) throws SQLException;
// 可选的钩子方法(支持子类扩展)
protected void beforeExecute(PreparedStatement ps) {}
protected void afterExecute(ResultSet rs) {}
}
子类继承并实现业务细节
每个具体实体对应一个子类,只需关注“做什么”,不重复写“怎么做”:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
buildQuerySql()返回该实体的查询 SQL(如"SELECT id, name FROM user") -
buildQueryParams()返回预编译参数列表(如空列表或带条件值) -
mapResultSet()将ResultSet映射为List<User>
示例(UserDao):
public class UserDao extends BaseDao<User> {
public UserDao(DataSource dataSource) {
super(dataSource);
}
@Override
protected String buildQuerySql() {
return "SELECT id, name, email FROM user WHERE status = ?";
}
@Override
protected List<Object> buildQueryParams() {
return Arrays.asList(1); // 查询启用用户
}
@Override
protected List<User> mapResultSet(ResultSet rs) throws SQLException {
List<User> users = new ArrayList<>();
while (rs.next()) {
User u = new User();
u.setId(rs.getLong("id"));
u.setName(rs.getString("name"));
u.setEmail(rs.getString("email"));
users.add(u);
}
return users;
}
}
支持增删改与事务增强
可在抽象类中扩展通用写操作模板:
- 添加
update(String sql, Object... params)方法,复用参数绑定与异常处理 - 提供
executeInTransaction(Supplier<T> action)方法,自动管理事务边界 - 利用
ThreadLocal<Connection>实现同一线程内连接复用(适用于手动事务场景)
例如事务方法片段:
public <R> R executeInTransaction(Supplier<R> action) {
try (Connection conn = dataSource.getConnection()) {
conn.setAutoCommit(false);
try {
R result = action.get();
conn.commit();
return result;
} catch (Exception e) {
conn.rollback();
throw e;
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
注意事项与优化建议
让模板更健壮实用:
- 使用
try-with-resources确保资源自动关闭,避免连接泄漏 - SQL 和参数分离,防止 SQL 注入;避免在抽象类中拼接 SQL 字符串
- 考虑引入泛型类型
T和主键类型ID,提升复用性(如BaseDao<T, ID>) - 如需更高灵活性,可将
ResultSet映射逻辑委托给独立的RowMapper<T>接口,解耦映射策略
不复杂但容易忽略。抽象类不是为了“多态”,而是为了把样板代码收拢,让每个 DAO 只专注自己的 SQL 和对象关系。

















