Spring Data:将多个存储库接口集成到一个“存储库”服务类

时间:2016-11-24 07:44:10

标签: java spring spring-data spring-data-jpa

由于数据库的设计,我有一些JpaRepository扩展的Repository接口。

为了构造一个简单的对象,即Person,我必须对大约4-5个存储库进行方法调用,因为数据在整个数据库中的传播方式都是如此。这样的事情(原谅伪代码):

@Service
public class PersonConstructService {

    public PersonConstructService(Repository repository,
                                  RepositoryTwo repositoryTwo,
                                  RepositoryThree repositoryThree) {

        public Person constructPerson() {
            person
                .add(GetDataFromRepositoryOne())
                .add(GetDataFromRepositoryTwo())
                .add(GetDataFromRepositoryThree());

            return person;
        }

        private SomeDataTypeReturnedOne GetDataFromRepositoryOne() {
            repository.doSomething();
        }

        private SomeDataTypeReturnedTwo GetDataFromRepositoryTwo() {
            repositoryTwo.doSomething();
        }

        private SomeDataTypeReturnedThree GetDataFromRepositoryThree() {
            repositoryThree.doSomething();
        }
    }
}

PersonConstructService类仅使用所有这些接口来构造一个简单的Person对象。我在PersonConstructService类中使用不同的方法调用这些存储库。我曾考虑将这个课程分成多个班级,但我认为这不正确。

相反,我想使用repositoryService,其中包括创建Person对象所需的所有存储库。这是一个好方法吗?春天有可能吗?

我问的原因是有时候注入服务的数量大约为7-8。这绝对不是好事。

2 个答案:

答案 0 :(得分:2)

我认为你不能/ shoudl创建一个像抽象一样的元库。存储库具有明确定义的含义,从概念上讲,它们对于Hibernate / JPA / Datastore实体来说是CRUD服务(有时更多:-))。我想这对他们来说已经足够了。更令人困惑的是。

现在我建议的是" smart"建立你的人的方式"自动(g)知道任何有助于Person对象含义的新服务的对象。

它的关键在于:

  • 您可以让您的存储库实现一个给定的接口,比如说PersonDataProvider,它有一个方法,比如public PersonPart contributeDataToPersonBuidler(PersonBuilder)
  • 您可以使@Service实现Spring的BeanFactoryPostProcessor接口,允许您检查所有此类PersonDataProvider实例的容器,并将它们注入您的服务(请参阅How to collect and inject all beans of a given type in Spring XML configuration处接受的答案)
  • 您的@Service实施将依次要求所有PersonDataProvider让他们提供他们的数据。

我可以扩展一下,但在我看来这就像是要走的路。

有人可能会说这不是很干净(这会使你的存储库意识到"某些东西"这种情况发生在服务层,他们不应该这样做),并且可以解决这个问题,但是#39;更容易以这种方式公开解决方案的要点。

编辑:自从这篇文章首次编写以来,我意识到Spring可以自动检测并注入某种类型的所有bean,而不需要PostProcessors。请在此处查看已接受的答案:Autowire reference beans into list by type

答案 1 :(得分:0)

我认为它是服务层上非常合理和实用的数据聚合。 它在Spring中完全可以实现。如果您可以访问存储库代码,则可以将它们命名为:

@Repository("repoOne")
public class RepositoryOne {

@Repository("repoTwo")
public class RepositoryTwo {

并根据需要将它们注入聚合服务:

@Service
public class MultipleRepoService {

    @Autowired
    @Qualifier("repoOne")
    private RepositoryOne repositoryOne;

    @Autowired
    @Qualifier("repoTwo")
    private RepositoryTwo repositoryTwo;

    public void doMultipleBusiness() {
        repositoryOne.one();
        repositoryTwo.two();
    }
}

事实上,如果它们是不同的类,你甚至不需要命名和限定它们,但如果它们是在层次结构中或具有相同的接口......

此外,如果不是自动装配,您可以直接注入构造方法:

public void construct(@Qualifier("repoOne")RepositoryOne repoOne,
                          @Qualifier("repoTwo")RepositoryTwo repoTwo) {
        repoOne.one();
        repoTwo.two();
    }