Java中可通过抽象类+泛型+反射(或JPA/MyBatis等框架)封装通用CRUD操作,子类仅需指定实体类型并关注业务逻辑;抽象基类声明泛型T和ID,保存Class<T>信息用于元数据解析,提供save、findById、findAll、deleteById等通用方法,并支持JPA或MyBatis集成。

在 Java 中,可以通过抽象类 + 泛型 + 反射(或配合 JPA/Hibernate/MyBatis 等框架)来封装通用的 CRUD 操作,让子类只需关注实体类型和特定逻辑,无需重复编写基础数据访问代码。
定义泛型抽象基类
抽象类声明一个类型参数 T,并要求子类指定具体实体类型。同时约定实体必须有主键字段(如 id),便于通用操作识别。
- 使用
Class<T>保存运行时类型信息,用于反射或 ORM 框架查找表名、字段等 - 提供 protected 的
entityClass字段,由子类构造器传入(避免运行时擦除) - 可定义统一的主键获取方式(例如通过
getId()方法,要求实体实现接口或约定)
封装通用增删改查方法
在抽象类中实现基于泛型的通用方法,例如:
-
save(T entity):插入或更新(根据主键是否为空判断) -
T findById(ID id):需额外声明第二个泛型参数ID(如Long或String) -
List<T> findAll():查询全部 -
void deleteById(ID id):按主键删除
这些方法内部可调用 JPA 的 JpaRepository、MyBatis-Plus 的 BaseMapper,或自己用 JDBC + 反射拼 SQL(不推荐生产环境裸写)。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
结合 JPA 实现示例
若使用 Spring Data JPA,可让抽象类继承 JpaRepository<T, ID> 并作为自定义实现基类:
public abstract class BaseRepositoryImpl<T, ID> implements JpaRepository<T, ID> {
private final Class<T> entityClass;
private final JpaEntityInformation<T, ?> entityInfo;
protected BaseRepositoryImpl(Class<T> entityClass) {
this.entityClass = entityClass;
this.entityInfo = JpaEntityInformationSupport.getEntityInformation(entityClass, entityManager());
}
// 复用 EntityManager 或调用父类默认实现
public T findFirstBy(String field, Object value) {
return getEntityManager().createQuery(
"SELECT t FROM " + entityClass.getSimpleName() + " t WHERE t." + field + " = :val",
entityClass)
.setParameter("val", value)
.getResultList()
.stream().findFirst().orElse(null);
}
}
子类只需声明:public class UserRepo extends BaseRepositoryImpl<User, Long> implements UserRepository { ... }
注意点与最佳实践
泛型抽象持久层要兼顾灵活性与安全性:
- 避免在抽象类中硬编码 SQL 表名或字段名;优先通过 JPA 注解或 MyBatis-Plus 的反射解析获取元数据
- 主键类型用独立泛型参数
ID,不要强制绑定为Long,以支持字符串 ID、UUID 等场景 - 事务控制交给子类或服务层,抽象类内不主动开启事务(除非明确设计为模板方法)
- 若用 MyBatis,可通过
@Mapper接口继承BaseMapper<T>,再由抽象 Service 类组合该 Mapper
这样设计后,每个新实体只需写一行继承代码 + 配置映射,即可获得完整的标准数据访问能力。

















