gpt4 book ai didi

java - 存储库设计模式——每个 Dao 都应该有一个存储库吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:03:25 24 4
gpt4 key购买 nike

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

我的意思是存储库应该只返回调用层理解的数据对象。所以它就像是对 DAO 的封装,但我不确定我是应该为每个 DAO 创建一个还是每个应用程序只有一个 repo,等等。

如果您阅读此 article我们开始明白该模式是过度设计或过度抽象的。它变成了隐藏细节与最小化查询语句。

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

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

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

最佳答案

我不确定这就是你要找的,但在我的应用程序中,我使用了描述的 DAO 模式和 Spring

So im confused on how many Repositories i would need.

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

下面是例子

定义常用的所有基本方法的接口(interface)

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();
}

}

Bar类相同

@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 是抽象的,因此您不能直接使用它,而是间接使用它,并且大多数常用方法都是通用的并且在层次结构中向上,这使它们成为可重用的理想候选者。

您可以从本书 Java Persistence with Hibernate 2nd Edition 中阅读更多相关信息

关于java - 存储库设计模式——每个 Dao 都应该有一个存储库吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44563979/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com