自定義Spring Data JPA存儲庫

Spring Data是一個非常方便的庫。 但是,由于該項目是一個相當新的項目,因此功能不佳。 默認情況下,Spring Data JPA將基于SimpleJpaRepository提供DAO的實現。 在最近的項目中,我開發了一個定制的存儲庫基類,以便可以在其上添加更多功能。 您可以根據需要向該存儲庫基類添加特定于供應商的功能。

組態

您必須在spring bean配置文件中添加以下配置。 您必須指定一個新的存儲庫工廠類。 我們將在以后開發課程。

<jpa:repositories base-package='example.borislam.dao' 
factory-class='example.borislam.data.springData.DefaultRepositoryFactoryBean/>

只需開發一個擴展JpaRepository的接口即可。 您應該記得用@NoRepositoryBean對其進行注釋。

@NoRepositoryBean
public interface GenericRepository <T, ID extends Serializable> extends JpaRepository<T, ID> {    
}

定義自定義存儲庫基礎實現類

下一步是開發定制的基礎存儲庫類。 您可以看到我只是這個自定義基礎存儲庫中的一個屬性(即springDataRepositoryInterface)。 我只想對存儲庫接口的自定義行為的行為進行更多控制。 在下一篇文章中,我將展示如何添加此基礎存儲庫類的更多功能。

@SuppressWarnings('unchecked')
@NoRepositoryBean
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>  implements GenericRepository<T, ID> , Serializable{private static final long serialVersionUID = 1L;static Logger logger = Logger.getLogger(GenericRepositoryImpl.class);private final JpaEntityInformation<T, ?> entityInformation;private final EntityManager em;private final DefaultPersistenceProvider provider;private  Class<?> springDataRepositoryInterface; public Class<?> getSpringDataRepositoryInterface() {return springDataRepositoryInterface;}public void setSpringDataRepositoryInterface(Class<?> springDataRepositoryInterface) {this.springDataRepositoryInterface = springDataRepositoryInterface;}/*** Creates a new {@link SimpleJpaRepository} to manage objects of the given* {@link JpaEntityInformation}.* * @param entityInformation* @param entityManager*/public GenericRepositoryImpl (JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager , Class<?> springDataRepositoryInterface) {super(entityInformation, entityManager);this.entityInformation = entityInformation;this.em = entityManager;this.provider = DefaultPersistenceProvider.fromEntityManager(entityManager);this.springDataRepositoryInterface = springDataRepositoryInterface;}/*** Creates a new {@link SimpleJpaRepository} to manage objects of the given* domain type.* * @param domainClass* @param em*/public GenericRepositoryImpl(Class<T> domainClass, EntityManager em) {this(JpaEntityInformationSupport.getMetadata(domainClass, em), em, null);  }public <S extends T> S save(S entity){     if (this.entityInformation.isNew(entity)) {this.em.persist(entity);flush();return entity;}entity = this.em.merge(entity);flush();return entity;}public T saveWithoutFlush(T entity){return super.save(entity);}public List<T> saveWithoutFlush(Iterable<? extends T> entities){List<T> result = new ArrayList<T>();if (entities == null) {return result;}for (T entity : entities) {result.add(saveWithoutFlush(entity));}return result;}
}

作為一個簡單的示例,我只是覆蓋了SimpleJPARepository的默認保存方法。 持久保存后,save方法的默認行為不會刷新。 我進行了修改,以使其在持久化后保持刷新狀態。 另一方面,我添加了另一個名為saveWithoutFlush()的方法,以允許開發人員調用保存實體而無需刷新。

定義自定義存儲庫工廠bean

最后一步是創建一個工廠bean類和一個工廠類,以根據您自定義的基本存儲庫類來生成存儲庫。

public class DefaultRepositoryFactoryBean <T extends JpaRepository<S, ID>, S, ID extends Serializable>extends JpaRepositoryFactoryBean<T, S, ID> {/*** Returns a {@link RepositoryFactorySupport}.* * @param entityManager* @return*/protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {return new DefaultRepositoryFactory(entityManager);}
}/*** * The purpose of this class is to override the default behaviour of the spring JpaRepositoryFactory class.* It will produce a GenericRepositoryImpl object instead of SimpleJpaRepository. * */
public  class DefaultRepositoryFactory extends JpaRepositoryFactory{private final EntityManager entityManager;private final QueryExtractor extractor;public DefaultRepositoryFactory(EntityManager entityManager) {super(entityManager);Assert.notNull(entityManager);this.entityManager = entityManager;this.extractor = DefaultPersistenceProvider.fromEntityManager(entityManager);}@SuppressWarnings({ 'unchecked', 'rawtypes' })protected <T, ID extends Serializable> JpaRepository<?, ?> getTargetRepository(RepositoryMetadata metadata, EntityManager entityManager) {Class<?> repositoryInterface = metadata.getRepositoryInterface();JpaEntityInformation<?, Serializable> entityInformation =getEntityInformation(metadata.getDomainType());if (isQueryDslExecutor(repositoryInterface)) {return new QueryDslJpaRepository(entityInformation, entityManager);} else {return new GenericRepositoryImpl(entityInformation, entityManager, repositoryInterface); //custom implementation}}@Overrideprotected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {if (isQueryDslExecutor(metadata.getRepositoryInterface())) {return QueryDslJpaRepository.class;} else {return GenericRepositoryImpl.class;}}/*** Returns whether the given repository interface requires a QueryDsl* specific implementation to be chosen.* * @param repositoryInterface* @return*/private boolean isQueryDslExecutor(Class<?> repositoryInterface) {return QUERY_DSL_PRESENT&& QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);}   
}

結論

現在,您可以向基礎存儲庫類添加更多功能。 在您的程序中,您現在可以創建自己的存儲庫接口,以擴展GenericRepository而不是JpaRepository。

public interface MyRepository <T, ID extends Serializable>extends GenericRepository <T, ID> {void someCustomMethod(ID id);  
}

在下一篇文章中,我將向您展示如何向此GenericRepository添加休眠過濾器功能。

參考: “ 編程和平”博客上的JCG合作伙伴 Boris Lam 自定義Spring Data JPA存儲庫 。


翻譯自: https://www.javacodegeeks.com/2012/08/customizing-spring-data-jpa-repository.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371546.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371546.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371546.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[基礎]PeopleSoft中的作業和調度作業集合定義

PeopleSoft進程調度器可以使一個或多個進程作為一個組。這個組在PeopleSoft中被稱為作業(Job)。 PeopleSoft進程被定義為單個任務&#xff0c;程序或例程&#xff0c;例如cobol程序或AE程序或客戶端運行的SQR。 作業由一個或多個相同或不同類型的進程組成&#xff0c;他們作為一…

體驗 WebFont,網頁上的藝術字

在最新項目中&#xff0c;由于要頻繁使用藝術字&#xff0c;而用戶設備沒有此字體&#xff0c;因此以往的經驗都是使用圖片...所以在同事的矚目期許之下&#xff0c;我開始實驗研究這個問題的解決方案1. 直接使用字體文件font-face {font-family: xxxx;src: url(../img/漢儀秀英…

linux文件分別打包命令,Linux文件打包命令

15.1 gzipgzip(1)是GNU的壓縮程序。它只對單個文件進行壓縮。基本用法如下&#xff1a;$ gzip filename程序執行以后&#xff0c;文件名會變成filename.gz&#xff0c;而且一般情況下大小會比原文件要小。注意&#xff0c;程序并不新建一個新的文件filename.gz,而是將filename變…

Play 2.0框架和XA交易

XA事務非常有用&#xff0c;而且開箱即用&#xff0c;今天的Play 2.0不支持它們。 在這里&#xff0c;我展示了如何添加該支持&#xff1a; 首先&#xff0c;介紹一些XA有用的示例&#xff1a; –如果您使用來自兩個不同persistence.xml的實體&#xff0c;則JPA使用兩個物理連…

java代碼注釋規范

java代碼注釋規范 一、規范存在的意義 應用編碼規范對于軟件本身和軟件開發人員而言尤為重要&#xff0c;有以下幾個原因&#xff1a;1、好的編碼規范可以盡可能的減少一個軟件的維護成本 , 并且幾乎沒有任何一個軟件&#xff0c;在其整個生命周期中&#xff0c;均由最初的開…

win10 hyper-v 虛擬機ping不通宿主機問題

在Windows10 Hyper-V 中安裝 Linux (Centos6.9)虛擬機無法 ping 通宿主機 這種情況下關閉 Windows 防火墻就能ping通了&#xff0c;當然關閉防火墻不安全。所以需要 做以下步驟: 控制面板-》系統和安全-》Windows防火墻-》高級設置-》入站規則 啟用下圖被紅框選中的兩個選…

linux方法參數,Linux的sysctl?命令?參數

Linux內核通過/proc虛擬文件系統向用戶導出內核信息&#xff0c;用戶也可以通過/proc文件系統或通過sysctl命令動態配置內核。比如&#xff0c;如果我們想啟動NAT&#xff0c;除了加載模塊、配置防火墻外&#xff0c;還需要啟動內核轉發功能。我們有三種方法&#xff1a;1. 直接…

Java枚舉:您擁有優雅,優雅和力量,這就是我所愛!

當Java 8即將面世時&#xff0c;您確定您對Java 5中引入的枚舉很了解嗎&#xff1f; Java枚舉仍然被低估了&#xff0c;很可惜&#xff0c;因為它們比您想象的要有用&#xff0c;它們不僅僅用于通常的枚舉常量&#xff01; Java枚舉是多態的 Java枚舉是可以包含行為甚至數據的…

C#刪除和清空文件夾的程序

/// <summary>/// 清空指定的文件夾&#xff0c;但不刪除文件夾/// </summary>/// <param name"dir"></param>private void DeleteFolder(string dir){foreach (string d in Directory.GetFileSystemEntries(dir)){if (File.Exists(d)){try{…

2)網頁請求順序

&#xff08;1&#xff09;分析瀏覽器訪問一個網頁的完整流程邏輯過程&#xff1a;http&#xff1a;//www.abc.com/def/ 轉載于:https://www.cnblogs.com/xiaoyoucai/p/7306246.html

JavaOne 2012:非阻塞數據結構如何工作?

當我查看今天的日程安排時&#xff0c;我感到有些驚訝&#xff0c;并指出我目前計劃今天參加的所有會議都在希爾頓舉行。 當我意識到JavaOne演示文稿中大約有一半是在希爾頓酒店中并且似乎按路線大致定位時&#xff0c;這變得有些不足為奇了。 Tobias Lindaaker &#xff08; 新…

c語言箭頭指針的作用,C語言中,結構體成員變量的點和箭頭

C語言中&#xff0c;調用成員變量用點還是用箭頭&#xff0c;取決于當前的ID是指針還是結構體本身。如&#xff1a;typedef struct {float height;float weight;} Person;int main(int argc, char *argv[]) {Person jiushen;Person *lengleng (Person *)malloc(sizeof(Person)…

JavaOne 2012:調查JVM水晶球

我回到了希爾頓的A / B廣場參加星期一的第四屆會議&#xff0c;但首先去了希爾頓的頂層收拾午餐。 我每年都在JavaOne的第一天被提醒&#xff0c;涉及到每個人的第一天的午餐獲取過程令人驚訝地令人沮喪。 我知道我在JavaOne的第一年的經歷使我有些困惑&#xff0c;因為我不確定…

測試遇到的問題

多人合作測試 多人員合作測試&#xff0c;應盡量保證測試平臺統一&#xff0c;處理流程統一&#xff0c;相互之間保持實時溝通。問題的處理進度應保證所負責的所有測試人員第一時間實時更新。 多人測試應做到2人或以上進行交叉測試。 轉載于:https://www.cnblogs.com/liuliu-wo…

Jquery Memo

jQuery選擇器 $( "#id" ) $( ".class" )$( "element" )全選擇器&#xff08;*選擇器&#xff09; * {padding: 0; margin: 0;}//子選擇器 //$(div > p) 選擇所有div元素里面的子元素P//后代選擇器 //$(div p) 選擇所有div元素…

c#語言輸出字符串長度,C#統計字符長度(漢字占2個字符)

在C#編程過程中&#xff0c;通過String類的Length屬性可以獲取對應字符串的長度&#xff0c;但是細心的讀者可能注意到了&#xff0c;String類的Length屬性返回的是字符串中Char對象的個數&#xff0c;也就是說&#xff0c;一個漢字的長度為1&#xff0c;對此&#xff0c;MSDN的…

使用JMSTester對JMS層進行基準測試

對于我去過的大多數客戶端&#xff0c;使用ActiveMQ擴展JMS消息傳遞層是一個優先事項。 有多種方法可以實現這一目標&#xff0c;但毫無疑問&#xff0c;創建基準測試并在實際硬件上分析架構&#xff08;或者正如我的同事Gary Tully所說的“詢問機器”&#xff09;是第一步。 但…

Js引擎解析執行 閱讀筆記

Js引擎解析執行 閱讀筆記 一篇閱讀筆記http://km.oa.com/group/2178/articles/show/145691?kmrefsearch&from_page1&no1 早期:遍歷語法樹 Js引擎最早使用的是遍歷語法樹方式 &#xff08;syntax tree walker&#xff09; 分為兩步 詞法分析語法分析詞法分析 i a b *…

紅外線遙控c語言程序,紅外遙控的C程序

紅外遙控在生產和生活中應用越來越廣泛,不同的紅外遙控芯片有不同的發碼協議,但一般都是由引導碼,系統碼,鍵碼三部分組成.引導碼是告訴接收機準備接收紅外遙控碼.系統碼是識別碼,不同的遙控芯片有不同的誤別碼,以免搞錯.遙控器上不同的按鍵有不同的鍵碼,系統碼和鍵碼都是16位碼…

Retrofit2 完全解析 探索與okhttp之間的關系

轉載請標明出處&#xff1a; http://blog.csdn.net/lmj623565791/article/details/51304204&#xff1b; 本文出自:【張鴻洋的博客】 之前寫了個okhttputils的工具類&#xff0c;然后有很多同學詢問這個工具類和retrofit什么區別&#xff0c;于是上了下官網&#xff0c;發現其底…