用泛型DAO封装CRUD让持久层代码翻倍提效

举报
小草飞上天 发表于 2026/08/16 08:15:01 2026/08/16
【摘要】 在Java后端开发中,数据持久化层(DAO层)的增删改查(CRUD)操作是极其高频的工作。许多开发者在初期为了图快,往往习惯性地为每一个实体类都手写一遍 save、findById、delete 等方法。这种“复制粘贴”不仅让代码库充斥着大量重复逻辑,一旦底层ORM框架(如Hibernate)的API发生变化,修改起来更是牵一发而动全身。为了解决这一痛点,我们可以利用Java的泛型机制,抽象...


在Java后端开发中,数据持久化层(DAO层)的增删改查(CRUD)操作是极其高频的工作。许多开发者在初期为了图快,往往习惯性地为每一个实体类都手写一遍 savefindByIddelete 等方法。这种“复制粘贴”不仅让代码库充斥着大量重复逻辑,一旦底层ORM框架(如Hibernate)的API发生变化,修改起来更是牵一发而动全身。

为了解决这一痛点,我们可以利用Java的泛型机制,抽象出一个通用的 GenericDAO 接口及其实现类。通过这种方式,所有的实体类都能免费复用基础的数据库操作,真正实现“一次编写,处处复用”。

一、 定义泛型DAO接口

首先,我们需要定义一个泛型接口。T 代表实体类类型,ID 代表主键类型(通常继承自 Serializable)。这个接口规范了所有实体必须具备的基础操作:

public interface GenericDAO<T, ID extends Serializable> {
    T findById(ID id);
    List<T> findAll();
    void save(T entity);
    void delete(T entity);
    long count();
}

二、 编写抽象实现类

接下来,我们提供一个抽象实现类。在这个类中,我们通过反射获取实体的 Class 对象,并注入全局的 SessionFactory。这样,所有的底层Session操作都可以被封装起来:

public abstract class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {
    protected Class<T> entityClass;
    protected SessionFactory sessionFactory;

    public GenericDAOImpl(Class<T> entityClass, SessionFactory sessionFactory) {
        this.entityClass = entityClass;
        this.sessionFactory = sessionFactory;
    }

    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public T findById(ID id) {
        return getSession().get(entityClass, id);
    }

    @Override
    public void save(T entity) {
        getSession().save(entity);
    }
    
    // findAll, delete, count 等方法同理省略...
}

三、 业务DAO的极简继承

有了上述的封装,当我们需要为具体的业务实体(例如博客系统中的 Article 文章实体)提供数据访问时,只需要继承 GenericDAOImpl 即可。从此,基础的增删改查再也不用手动编写了:

@Repository
public class ArticleDAO extends GenericDAOImpl<Article, Long> {
    
    public ArticleDAO(SessionFactory sessionFactory) {
        super(Article.class, sessionFactory);
    }

    // 遇到复杂的业务查询,只需在此处扩展自定义方法
    public List<Article> findPublishedArticles() {
        return getSession().createQuery(
            "FROM Article a WHERE a.status = :status ORDER BY a.createTime DESC", Article.class)
            .setParameter("status", ArticleStatus.PUBLISHED)
            .list();
    }
}

通过这种面向抽象的泛型设计,我们不仅大幅减少了代码量,提高了开发效率,还让持久层的结构变得更加清晰。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。