本節書摘來自異步社群《spring data實戰》一書中的第2章,第2.1節,作者: 【美】mark pollack , oliver gierke , thomas risberg , jon brisbin , michael hunger著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
長期以來,實作應用程式的資料通路層一直是件繁瑣的工作,因為我們經常需要編寫大量的樣闆式代碼,而且貧血(anemic)的領域類并沒有按照真正面向對象或領域驅動方式來進行設計。是以spring data repository抽象的目标就是大幅簡化各種持久化存儲持久層的實作。我們将會使用spring data jpa子產品作為例子來讨論repository抽象的基本理念。對于其他類型的存儲,可以參考對應的例子。
我們選取領域模型中的customer領域類,它會被持久化到任意的存儲之中。這個類應該如示例2-1所示。
示例2-1 customer領域類

傳統的實作資料通路層的方式至少需要實作一個存儲類(repository class),這個類會包含基本的crud(create、read、update與delete)方法以及通過限制條件來通路實體子集的查詢方法。spring data repository的方式能夠避免大多數的代碼,隻需為這個實體存儲聲明簡單的接口定義即可,如示例2-2所示。
示例2-2 customerrepository接口定義
正如你所見,我們擴充了spring data的repository接口,它是通用的辨別接口。它的主要職責是讓spring data的基礎設施識别出所有使用者定義的spring data repository。除此之外,它還會捕獲托管的領域類以及實體的id類型,稍後這些功能會提供很大的便利性。為了能夠自動發現所聲明的接口,可以使用存儲特定的xml命名空間中的元素(如示例2-3所示),或是在使用javaconfig時借助相關的@enable...repositories注解(如示例2-4所示)。在示例中會使用jpa。我們隻需将xml元素的base-package屬性配置為我們的根包(root package),spring data會掃描它來查找repository接口。如果沒有給出更進一步的配置,那麼它隻會簡單地檢查包中帶有注解的類。
示例2-3 使用xml激活spring data repository
示例2-4 使用java config激活spring data repository
xml和javaconfig配置都需要添加存儲專用的bean聲明來進行完善,如jpa的entitymanagerfactory以及datasource等。對于其他形式的存儲,我們隻需使用對應的命名空間元素或注解即可。例如,示例2-5所示的配置片段,将會找到spring data repository并建立spring bean,這些bean實際上是由一組實作了所發現接口的代理所組成的。是以,現在可以繼續編寫用戶端,通過spring的自動裝配就能通路這個bean了。
customerrepository接口建立之後,我們就可以繼續深入學習并添加一些易于聲明的查詢方法。常見的需求是通過電子郵件位址來擷取customer。為了做到這一點,我們添加合适的查詢方法,如示例2-6所示。
示例2-5 用戶端使用spring data repository
示例2-6 聲明查詢方法
命名空間元素将會在容器啟動的時候掃描到這個接口并觸發spring data的基礎設施為其建立spring bean。基礎設施會探查接口中聲明的方法并确定方法調用時要執行的查詢。如果隻是這樣簡單地定義方法的話,那麼spring data将會根據其名字衍生出一個查詢。在定義查詢方面還有其他的途徑可選,可以閱讀2.2小節“定義查詢方法”來了解更多資訊。
在示例2-6中,由于我們遵循了領域對象屬性的命名約定,因而查詢可以衍生得到。查詢方法名中的emailaddress部分其實就對應了customer類的emailaddress屬性,是以,在使用jpa子產品時,spring data會自動為聲明的方法衍生出select c from customer c where c.emailaddress = ?1。它還會檢查方法聲明中屬性引用的合法性,如果發現任何錯誤則會在容器啟動時,出現啟動失敗。現在,用戶端可以很容易地執行這個方法,給定的方法參數會綁定到根據方法名衍生出來的查詢之中并且執行該查詢,如示例2-7所示。
示例2-7 執行查詢方法