如何创建提供crud操作的通用DAO,而无需通过不提供其他方法的自定义DAO扩展它

时间:2016-08-12 12:29:30

标签: java spring hibernate generics jpa

我是通用DAO:

@NoRepositoryBean
interface ICrudDao<T, ID extends Serializable> extends Repository<T, ID> {
    void delete(T deleted);

    List<T> findAll();

    T findOne(ID id);

    T save(T persisted);
}

为了允许服务工作,我必须创建允许自定义实体获得持久性的接口,例如:

interface TodoDao extends ICrudDao<Todo, Long> {

}

我有很多像TodoDao这样的人。然后不要提供任何特殊方法。

创建大量空接口似乎是一个愚蠢的想法。如何创建一个通用的?

3 个答案:

答案 0 :(得分:2)

修改 我不认为你想要做的是一个好主意。最初为每个实体注册一个存储库看起来像锅炉板代码,但随着应用程序的增长,它将帮助您维护它。想象一下你的应用程序会随着时间的推移而发展:

  1. 您创建一个简单的实体Person和Interface PersonRepository。幸运的是,所有基本的CRUD操作都包含在内,到目前为止它符合您的需求,因此没有其他事可做。
  2. 随着应用程序的增长,Person会获得许多关联关系,例如地址,作业,爱好,每次访问时都会获取所有关联数据效率非常低,因为并不总是需要每个关联。要遇到这种情况,您需要在PersonRepository中创建自己的方法,该方法执行您自己的NamedQuery以仅加载某些字段并将其存储在特定视图所需的DTO中(&#34; SELECT new package.PersonDto(x,y)FROM PERSON WHERE ...)。
  3. 随着时间的推移,您会发​​现自己需要以动态方式执行查询,例如只需要在某些条件下添加的分页或限制。因此,您创建一个新的接口PersonCustomRepository和PersonCustomRepositoryImpl,以编程方式编写查询:

    @PersistenceContext
    private EntityManager entityManager;
    
    @Transactional
    public List<Person> foo() {
       // example for accessing hibernate directly, you could also use QueryDSL and so on
       Criteria basicCriteria = entityManager.unwrap().createCriteria(Person.class);
       if (someCondition) {
          criteria.add(Restrictions.eq("foo", foo));
          ...
       }
       ...
       return criteria.list();
    }
    
  4. 底线: Spring数据存储库已经为您做了很多工作,它们很容易扩展,不会尝试对抗您的框架,即使它可能会为您节省一些点击第一名。

答案 1 :(得分:1)

您可以通过使实体成为通用来避免这种情况。

//you can annotated with @MappedSuperclass
public class BaseBean{
 //you can specify the id here
}

public class Todo extends BaseBean {

}

@NoRepositoryBean
interface ICrudDao<T exntends BaseBean, ID extends Serializable> extends Repository<T, ID> {
    void delete(T deleted);

    List<T> findAll();

    T findOne(ID id);

    T save(T persisted);
}

答案 2 :(得分:0)

我认为不可能。请参阅How to create a Generic DAO class using Hibernate Context sessionsHibernate: CRUD Generic DAO这些可能有所帮助。 我还可以将Hibernate Session视为处理所有类型对象持久性的单个类的示例,它只处理对象类型。