跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

泛型在DAO层设计中实现通用CRUD操作的模版化

泛型DAO通过解耦数据操作逻辑与实体类型实现CRUD复用,支持MyBatis-Plus的BaseMapper或手写抽象类,需规避复杂查询、统一主键并保持DAO职责纯粹。 泛型在DAO层设计中能有效消除重复代码,让增删改查操作适配任意实体类型,核心是把“数据操作逻辑”和“具体实体类型”解耦。 定义通用DAO接口 用泛型声明接口,约束所有实现类必须支持指定类型的CRUD: T 代表实体类(如 User、Order),通常要求有主键字段 接口方法不依赖具体表结构,只约定行为:save、findById、update、deleteById、findAll 可配合 extends Serializable 或自定义标识接口(如
BaseEntity
)确保类型安全 基于MyBatis-Plus的泛型实现 MyBatis-Plus 提供了
BaseMapper
,天然支持泛型,只需让各Mapper接口继承它:
public interface UserMapper extends BaseMapper {}
public interface OrderMapper extends BaseMapper {}
无需写XML,
insert
、
selectById
等方法开箱即用 若需扩展通用逻辑(如软删除统一处理),可封装一个
GenericMapper
抽象类继承
BaseMapper
,再由各Mapper继承它 手写泛型DAO抽象类(JDBC/MyBatis原生场景) 当不使用MyBatis-Plus时,可通过反射+泛型擦除规避类型丢失问题: 抽象类构造时通过
getGenericSuperclass()
获取子类实际传入的泛型类型
T
用
BeanPropertyRowMapper
(Spring JDBC)或
ResultSet
反射赋值,确保查询结果正确映射到
T
增删改语句用占位符,字段名可通过注解(如
@TableId
、
@TableName
)或反射实体类提取,避免硬编码 关键点:抽象类本身不指定
T
,而是由子类明确,如
public class UserDAO extends GenericDAO
注意事项与边界控制 泛型DAO不是万能模板,需主动规避风险: 复杂查询(多表关联、聚合)不宜强行塞进通用接口,应保留在具体Mapper中 主键策略要统一(如都用Long型id),否则
findById(Long id)
无法通用;若存在String主键,可定义泛型参数
事务、缓存、分页等横切关注点,建议通过AOP或Service层统一处理,DAO保持纯粹数据访问职责 单元测试时,对泛型基类做一次覆盖验证即可,不必为每个实体重复测基础CRUD

相关文章