3

我对 DDD 和 JPA 很陌生。

我正在使用 JPA 和 Spring 开发一个通用存储库。我真的很喜欢文章DDD:通用存储库JPA 实现模式:数据访问对象中公开的方法。我的目标是使用 JPA 和 Spring 在领域驱动设计中构建完美的存储库。

遵循第一篇文章的概念,我使用内部通用存储库来尊重域与数据存储的合同。

public interface IInternalGenericRepository<K, E> {
    List<E> read(String query, Object[] params);
    void persist(E entity);
    void remove(E entity);
}

public class InternalGenericRepository<K, E> implements IInternalGenericRepository<K, E> {

    // Injected through DI in Spring
    @PersistenceContext
    private EntityManager em;

    private final Class<E> entityClass;

    public List<E> read(String query, Object[] params) {
        Query q = em.createQuery(query);
        for (int i = 0; i < params.length; i++) {
            q.setParameter(i + 1, params[i]);
        }
        return q.getResultList();
    }

    public void persist(E entity) {
        em.persist(entity);
    }

    // ...
}

然后,特定实体(例如:组织)的存储库如下所示。

public interface IOrganizationRepository {
    List<Organization> organizationByCityName(String city);

    void create(Organization o);
}


@Repository
public class OrganizationRepository implements IOrganizationRepository {

    @Autowired
    IInternalGenericRepository<Long, Organization> internalRepository;

    public List<Organization> organizationByCityName(String city) {
        Object[] params = new Object[1];
        params[0] = city;
        return internalRepository.read("select o from Organization o where o.city.name like ?1",
                params);
    }

    @Override
    public void create(Organization o) {
        internalRepository.persist(o);
    }
}

它看起来像是用 JPA 和 Spring 实现 DDD 存储库的好方法。然后将 OrganizationRepository 注入我的服务层。

我希望有外部观点以避免缺陷或误解。您怎么看?如何改进?

谢谢。


编辑:

  • @Autowired on internalRepository - 感谢 axtavt 指出。
  • read() 可以改进
4

1 回答 1

1

首先,它不起作用,因为 Spring 无法注入EntityManager使用new. 所以,你必须写这样的东西:

public class OrganizationRepository implements IOrganizationRepository { 

    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        internalRepository.em = em;
    }
    ...
}

此外,您的read方法看起来有点过于笼统。它遗漏了一些重要的用例,例如getSigleResultand setFirstResult/ setMaxResults

就我个人而言,我更喜欢第二篇文章 apporach,因为使用组合你最终会拥有EntityManagerinOrganizationRepository来实现IInternalGenericRepository.

于 2010-02-10T20:05:38.987 回答