2016-11-24 47 views
2

由於數據庫的設計,我有相當多的JpaRepository擴展的存儲庫接口。Spring Data:將多個存儲庫接口合併到一個「存儲庫」服務類

爲了構建一個簡單的對象,例如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。這絕對不好。

+0

有了Spring,你可以首先使用'@ Autowired'註釋來讓你的服務在你的類中準備好使用,但是你不應該直接調用你的類'PersonConstructService'的存儲庫方法。這不是問題,如果你的班級需要7個服務,爲什麼稱這7個服務爲壞?我猜如果你的POJO與(@ @ ManyToOne','@ OneToMany'等)之間的關係綁定在一起,你可以簡單地構造你的對象而不需要手動添加其他對象。 – Alex

+0

@Alex那麼,如果你的類構造函數中有很多服務,據我所知是一個根據Spring Docs的代碼氣味:'作爲一個附註,大量的構造函數參數是一種不好的代碼味道,這意味着這個類可能有太多的責任,應該重構,以更好地解決問題的正確分離。「您是否建議通過以下方式進行現場注入:\t '使用Spring,您可以首先使用@Autowired註釋讓您的服務隨時可用於您的課堂'? –

+0

完全是。構造函數參數是一件事情,但注入你的服務是另一種正確地完成你想要的東西的方法。 Java EE已經在v6中用'@ Inject'實現了這個,Spring的官方關鍵字是'@ Autowired',並且我個人有時會在我的一些類中有6或7個類。我從來沒有目睹特定問題 – Alex

回答

2

我不認爲你可以/ shoudl創建一個像抽象的元庫。存儲庫具有明確定義的含義,從概念上講,它們是您的Hibernate/JPA/Datastore實體的CRUD服務(有時更多:-))。我想這對他們來說已經足夠了。更多的是混亂。

現在我要提出的是一種「智能」的方法來構建自動化的「人」對象,以便意識到任何有助於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)然後
  • 你@服務的實現是要求所有的PersonDataProvider輪流要求他們提供他們的數據。

我可以擴大一點,但在我看來,似乎要走的路。

有人可能會認爲這不是乾淨的(它會讓您的知識庫知道發生在服務層的「某些事情」,而且他們不應該這樣做),並且可以解決這個問題,但是更簡單的方法是公開這種解決方案的主旨。

編輯:由於這篇文章是第一次編寫的,我意識到Spring可以自動檢測並注入某種類型的所有bean,而不需要PostProcessors。看到接受的答案在這裏:Autowire reference beans into list by type

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(); 
    } 
相關問題