Spring + Hibernate DAO 作为泛型类

Posted

技术标签:

【中文标题】Spring + Hibernate DAO 作为泛型类【英文标题】:Spring + Hibernate DAO as generic class 【发布时间】:2015-06-29 23:57:18 【问题描述】:

前段时间我开始学习java EE。我迅速转向 spring(mvc)+hibernate。当我学习数据库和与 spring+hibernate 的集成时,我想到了一个想法。

据我注意到(并理解)有一种通用的方法来构建对象结构,包括配置文件、实体、dao 接口和 dao 实现(因为我们只讨论 dbs,而不是控制器和其他应用程序的层) .我决定编写一个通用的 java 类并将其命名为BasicDao是以实体为类型的模板。

这实际上是有效的,我认为它比接口和实现要好得多,因为所有实体只需要一个类(如果你想为每个实体编写单独的实现,你最终可能会得到大量文件)。

我还在那里编写了一些模板函数,因此该类非常灵活(传递给数据库的类型没有例外)。这是代码

package local.bb.dao;

import java.util.List;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository(value = "basicDao")
@Transactional(propagation = Propagation.REQUIRED,readOnly = true)
public class BasicDao<ENTITY> 

    private Class<ENTITY> data;
    private SessionFactory sessionFactory;

    public BasicDao() 
        this.data = null;
    

    @Transactional
    public void addRecord(ENTITY t) 
        this.sessionFactory.getCurrentSession().save(t);
    

    @Transactional
    public void removeRecord(ENTITY t) 
        this.sessionFactory.getCurrentSession().delete(t);
    

    @Transactional
    public List<ENTITY> getAllRecords() 
        return (List<ENTITY>)this.sessionFactory.getCurrentSession().createCriteria(this.data).list();
    

    @Transactional
    public <TYPE> ENTITY getRecordByParam(String param, TYPE value) 
        return (ENTITY)this.sessionFactory.getCurrentSession().createCriteria(this.data).add(Restrictions.eq(param, value)).uniqueResult();
    

    @Transactional
    public <TYPE> List<ENTITY> getRecordsByParam(String param, TYPE value) 
        return (List<ENTITY>)this.sessionFactory.getCurrentSession().createCriteria(this.data).add(Restrictions.like(param, value)).list();
    

    //  GETTERS / SETTERS

    public SessionFactory getSessionFactory() 
        return sessionFactory;
    


    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) 
        this.sessionFactory = sessionFactory;
    

    public Class<ENTITY> getData() 
        return data;
    

    public void setData(Class<ENTITY> data) 
        this.data = data;
    



最后的问题是:这实际上是一个好方法吗?因为我从来没有在任何地方看到过这样的代码(谈到互联网上的教程和书籍)。

【问题讨论】:

由于您使用的是 Spring 和 Hibernate,因此 Spring Data JPA 项目对您来说应该是一本不错的读物。无需重新发明***,除非出于学习目的。但即便如此,Spring Data JPA 也是如何做到这一点的一个很好的例子。 projects.spring.io/spring-data-jpa YAGDI(又一个通用的 Dao 实现)。互联网上有severalimplementations 用于通用dao 模式。与其自己编写一个可用的,不如使用 Spring Data JPA,你根本不需要实现...... 【参考方案1】:

Spring 喜欢接口,因为有几个重要的机制基于它,例如AOP,拦截器。因此,如果您决定不使用它们,则必须接受 Spring 功能的某些限制。更重要的是,为其他依赖于您的 DAO 的类编写 Test-Mocks 将更加困难。

如果你想节省代码,我建议你失去实现而不是接口。使用 Spring JPA,您可以使用一组注释来注释 DAO 接口,即@Query, @Procedure, @Modifying 等,以定义如何访问数据。如果您随后在应用程序上下文中启用 JPA 存储库,Spring 将为您提供 DAO 实现。

更多信息可以在here找到。

【讨论】:

【参考方案2】:

是的,您可以在 hibernate 中编写通用 DAO,如果它有用并且可以帮助您减少大量代码并使代码库变得干净,那么您应该使用它。我使用了通用 DAO,但仅用于简单的 CRUD 操作。 Here 是通用持久层的好读物。

【讨论】:

以上是关于Spring + Hibernate DAO 作为泛型类的主要内容,如果未能解决你的问题,请参考以下文章

Spring整合DAO与Hibernate

Spring 3,带有通用 DAO 的 Hibernate 4 AutoWired sessionFactory

Spring 和 Hibernate:DAO 模式。如何解决 LazyInitializationException

DAO、Spring 和 Hibernate

Spring 与 Hibernate DAO 层?

在 Spring Boot 中使用 Hibernate 为 DAO 层配置单元测试