1.概述
本文將重點介紹Spring 3.1,JPA和Spring Data的持久層的配置和實現。 有關使用基于Java的配置和項目的基本Maven pom設置Spring上下文的分步介紹,請參閱本文 。
持久性與春天 系列 :
- 第1部分 – 具有Spring 3.1和Hibernate的持久層
- 第2部分 – 使用Spring和Java泛型簡化數據訪問層
- 第3部分 – 具有Spring 3.1和JPA的持久層
- 第4部分 – 使用Spring Data JPA的持久層
- 第5部分 – 使用JPA和Spring 3.1進行事務配置
2.沒有更多的DAO實現
如前一篇文章中所討論的, DAO層通常包含許多可以并且應該簡化的樣板代碼。 這種簡化的優點有很多方面:減少需要定義和維護的工件數量,簡化和簡化數據訪問模式并保持配置一致性。
Spring Data將這一簡化向前邁了一步,并且有可能完全刪除DAO實現-DAO的接口現在是唯一需要明確定義的工件。
3. Spring Data管理的DAO
為了開始通過JPA使用Spring Data編程模型,DAO接口需要在Spring的接口層次結構中擴展JPA特定的Repository接口– JpaRepository 。 這將使Spring Data能夠找到該接口并為其自動創建一個實現。
此外,通過擴展接口,我們可以獲得DAO中可用的大多數(即使不是全部)相關的CRUD通用方法來進行標準數據訪問。
4.定義自定義訪問方法和查詢
如上所述,通過實現存儲庫接口之一,DAO將已經定義和實現了一些基本的CRUD方法(和查詢)。 為了定義更具體的訪問方法,Spring JPA支持許多選項–您可以在界面中簡單地定義一個新方法 ,或者可以使用@Query注釋提供實際的JPQ查詢 。
定義自定義查詢的第三個選項是使用JPA命名查詢,但這具有以下缺點:要么涉及XML,要么使查詢負擔域類。
除了這些之外,Spring Data 引入了更靈活和方便的API,類似于JPA Criteria API,只是更具可讀性和可重用性。 當處理大量固定查詢時,此API的優勢將變得更加明顯,這些固定查詢可以通過較少數量的可重復使用的塊(以不同的組合形式不斷出現)來更簡潔地表達。
4.1。 自動自定義查詢
當Spring Data創建一個新的Repository實現時,它會分析接口定義的所有方法,并嘗試根據方法名自動生成查詢。 盡管這有局限性,但它是一種非常有用且優雅的方法,可以輕松定義新的自定義訪問方法。
例如,如果管理實體具有名稱字段(以及該字段的Java Bean標準getter和setter),則在DAO接口中定義findByName方法將自動生成正確的查詢:
public interface IFooDAO extends JpaRepository< Foo, Long >{Foo findByName( final String name );}
這是一個相對簡單的例子。 查詢創建機制支持更多的關鍵字集 。
如果解析器無法將該屬性與域對象字段匹配,則會引發以下異常:
java.lang.IllegalArgumentException:未為類型類org.rest.model.Foo找到屬性nam
4.2。 手動自定義查詢
除了從方法名稱派生查詢外,還可以使用方法級別@Query注釋手動指定自定義查詢。
為了對查詢的創建進行更精細的控制,例如使用命名參數或修改現有查詢, 該參考是一個不錯的起點。
5. Spring Data事務配置
Spring Data托管DAO的實際實現-SimpleJpaRepository-使用注釋來定義和配置事務 。 在類級別使用只讀@Transactional批注,然后將其替換為非只讀方法。 其余的事務語義是默認的,但是可以很容易地按方法手動覆蓋它們。
5.1。 沒有模板的異常翻譯
Spring ORM模板( JpaTemplate , HibernateTemplate )的職責之一是異常轉換 -將JPA異常(將API與JPA關聯) 轉換為Spring的DataAccessException層次結構。
沒有模板可以執行此操作,仍然可以通過使用@Repository批注對DAO進行批注來啟用異常轉換。 結合使用Spring bean后處理器,將為所有@Repository bean提供在Container中找到的PersistenceExceptionTranslator的所有實現–無需使用模板即可提供異常轉換。
異常轉換確實有效的事實可以通過集成測試輕松驗證:
@Test( expected = DataAccessException.class )
public void whenAUniqueConstraintIsBroken_thenSpringSpecificExceptionIsThrown(){String name = "randomName";service.save( new Foo( name ) );service.save( new Foo( name ) );
}
異常翻譯是通過代理完成的; 為了使Spring能夠圍繞DAO類創建代理,不得將它們聲明為final 。
6. Spring數據配置
為了激活Spring JPA存儲庫支持,定義了jpa命名空間并將其用于指定DAO接口所位于的包:
<?xml version="1.0" encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jpa="http://www.springframework.org/schema/data/jpa"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/data/jpahttp://www.springframework.org/schema/data/jpa/spring-jpa.xsd"><jpa:repositories base-package="org.rest.dao.spring" /></beans>
在這一點上,沒有等效的基于Java的配置–然而,對它的支持正在進行中 。
7. Spring Java或XML配置
該系列的上一篇文章已經詳細討論了如何在Spring 3中配置JPA 。 Spring Data還利用了對JPA @PersistenceContext批注的Spring支持,該批注用于將EntityManager連接到負責創建實際DAO實現的Spring工廠bean – JpaRepositoryFactoryBean 。
除了已經討論過的配置之外,還有最后一個缺失的部分–包括整體持久性配置中的Spring Data XML配置:
@Configuration
@EnableTransactionManagement
@ImportResource( "classpath*:*springDataConfig.xml" )
public class PersistenceJPAConfig{...
}
8. Maven配置
除了上一篇文章中定義的JPA的Maven配置之外,還添加了spring-data-jpa依賴項:
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>1.3.2.RELEASE</version>
</dependency>
9.結論
本文介紹了使用基于XML和Java的配置以及Spring 3.1,JPA 2和Spring JPA(屬于Spring Data傘項目的一部分)的持久層的配置和實現。 討論了定義更高級的自定義查詢的各種方法,以及使用新的jpa名稱空間和事務語義的配置。 最終結果是對Spring進行數據訪問的一種新穎而優雅的方式,幾乎沒有實際的實現工作。 您可以在github項目中查看完整的實現。
翻譯自: https://www.javacodegeeks.com/2011/12/persistence-layer-with-spring-data-jpa.html