仓库设计模式-每个Dao应该有一个仓库吗? [英] Repository design pattern - should there be one repo for every Dao?

查看:153
本文介绍了仓库设计模式-每个Dao应该有一个仓库吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一些DAO,可以访问数据库进行CRUD操作.可以说有新闻,天气和体育DAO.我对我需要多少个存储库感到困惑.我应该只使用一个存储库,比如说DataRepository,让我保存我的数据库和所有dao的数据库.并封装CRUD操作的方法吗?还是每个DAO都有自己的存储库?

i have a few DAOs in my app which access a database for CRUD operations. Lets say there News, weather and , sports DAO. So im confused on how many Repositories i would need. should i just use one repository say DataRepository and let me hold my database and all dao's. and encapsulate methods for the CRUD operations in it ? or should each DAO have its own repository ?

我的意思是,存储库应该只返回调用层可以理解的数据对象.因此,这就像对DAO的封装,但是我不确定我应该为每个DAO创建一个还是每个应用仅创建一个回购协议,等等.

I mean a repository should return only data objects that the calling layer understands. so its like a encapsulation over the DAOs but im not sure if i should create one per DAO or just have one repo per app, etc.

如果您阅读了文章,我们开始了解到模式过度设计或过度抽象.它变成了隐藏细节与最小化查询语句.

If you read this article we begin to understand that the pattern is over engineered or over abstracted. Its turned into hiding detail vs minimizing query statements.

但是似乎每个DAO都应该有一个Repo,因为接口本身看起来像这样:

But it seems There should be a Repo per DAO as the interface itself looks like this:

interface Repository<T> {
void add(T item);
void remove(Specification specification);
List<T> query(Specification specification);

}

其中T可以是数据DAO访问的类型/表.现在只需要澄清即可.您能想象我有30种不同的类型,所以我需要30种不同的Repo实现.这是荒唐的.似乎存储库模式本身就像是DAO,没有什么不同.我很混乱.

where T can be the type/table of data DAO accesses. Just need clarification now. Can you imagine i have 30 different types, so then i need 30 different Repo implementations. this is ridiculous. It seems the repository pattern itself is like a DAO, no different. im so confused.

推荐答案

我不确定这就是您要查找的内容,但是在我的应用程序中,我将所描述的DAO模式与Spring

I am not sure this is what all you looking for but In my application I am using described DAO pattern with Spring

所以我对我需要多少个存储库感到困惑.

So im confused on how many Repositories i would need.

恕我直言,每个实体至少需要一个存储库,因为它们可以简化设计,但是由于您使它们通用,并且它们处于层次结构中,因此可以简单地与子类/接口一起使用

IMHO you will need at least single Repository for each entity as they lead to simple design but since you are making them generic and they are up in hierarchy, can be used simply with child classes/interfaces

下面是示例

用于定义所有常用方法的接口

Interface to define all basic methods that to use commonly

public interface GenericDAO<T, ID extends Serializable> {


    T findById(ID id, LockModeType lock);

    void save(T entity);

    T update(T entity);

    List<T> findAll();
}

通用实现

public abstract class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {

    @PersistenceContext
    protected EntityManager em;

    private final Class<T> entityClass;

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

    @Override
    public T findById(ID id, LockModeType lock) {
        return em.find(entityClass, id, lock);
    }

    @Override
    public void save(T entity) {
        em.persist(entity);

    }

    @Override
    public T update(T entity) {
        return em.merge(entity);
    }

    @Override
    public List<T> findAll() {
        CriteriaQuery<T> c = em.getCriteriaBuilder().createQuery(entityClass);
        c.select(c.from(entityClass));
        return em.createQuery(c).getResultList();
    }
.
.
.
}

Foo类

@Entity
public class Foo implements Serializable {

    private static final long serialVersionUID = 1L;
    private Long id;
    private String text;
}

Foo存储库

public interface FooRepositiry extends GenericDAO<Foo, Long> {

    Foo findTextById(Long id);

}

实施的Foo存储库

@Transactional
@Repository
public class FooRepoImpl extends GenericDAOImpl<Foo, Long> implements FooRepositiry {

    public FooRepoImpl() {
        super(Foo.class);
    }

    @Override
    public Foo findTextById(Long id) {
        CriteriaQuery<Foo> c = em.getCriteriaBuilder().createQuery(Foo.class);
        // .
        // .
        // .
        return em.createQuery(c).getSingleResult();
    }

}

与酒吧课相同

@Transactional
@Repository
public class BarRepoImpl extends GenericDAOImpl<Bar, Long> implements BarRepo {

    public BarRepoImpl() {
        super(Bar.class);
    }

    @Override
    public List<Bar> findAllBarWithText(String text) {
        CriteriaQuery<Bar> c = em.getCriteriaBuilder().createQuery(Bar.class);
        return em.createQuery(c).getResultList();
    }
}

此处,此通用实现需要完成两项工作:EntityManager和 实体类.子类必须提供实体类作为构造函数参数. EntityManager是通过使用PersistenceContext提供的,或者您可以使用getter-setter方法来实现.由于GenericDAOImpl是抽象的,因此您不能直接使用它,而可以间接使用它,并且大多数常用的方法是通用的并且在层次结构中较高,这使它们成为重用的理想候选对象.

Here this generic implementation needs two things to work: an EntityManager and an entity class. A subclass must provide the entity class as a constructor argument. EntityManager is provided by using PersistenceContext or you can use getter-setter methods for the same. Since GenericDAOImpl is abstract threfore you cannot use it directly but Indirectly and most of the commnoly used methods are generic and up in hierarchy which makes them Ideal candidate to be reused.

您可以从使用Hibernate进行Java持久性第二版

这篇关于仓库设计模式-每个Dao应该有一个仓库吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆