日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring Data JPA 从入门到精通~自定义实现Repository

發(fā)布時(shí)間:2024/7/23 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Data JPA 从入门到精通~自定义实现Repository 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

EntityManager 的獲取方式

我們既然要自定義,首先講一下 EntityManager 的兩種獲取方式。

1. 通過(guò) @PersistenceContext 注解。

通過(guò)將 @PersistenceContext 注解標(biāo)注在 EntityManager 類(lèi)型的字段上,這樣得到的 EntityManager 就是容器管理的 EntityManager。由于是容器管理的,所以我們不需要也不應(yīng)該顯式關(guān)閉注入的 EntityManager 實(shí)例。

@Repository @Transactional(readOnly = true) public class UserRepositoryImpl implements UserRepositoryCustom {@PersistenceContext //獲得entityManager的實(shí)例EntityManager entityManager; }

2. 繼承 SimpleJpaRepository 成為子類(lèi),實(shí)現(xiàn)構(gòu)造方法即可,這時(shí)候我們直接用父類(lèi)里面的 EntityManager 即可。

public class BaseRepositoryCustom<T, ID> extends SimpleJpaRepository<T, ID> {public BaseRepositoryCustom(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {super(entityInformation, entityManager);}public BaseRepositoryCustom(Class<T> domainClass, EntityManager em) {super(domainClass, em);} }

自定義 Repository 的兩種場(chǎng)景

我們自定義實(shí)現(xiàn) Repository,主要的應(yīng)用場(chǎng)景有兩種:

  • 個(gè)別特殊化場(chǎng)景,私有的。
  • 公用的通用的場(chǎng)景,替代默認(rèn)的 SimpleJpaRepository 的場(chǎng)景,架構(gòu)層面出發(fā)。

1. 自定義個(gè)別的特殊場(chǎng)景,私有的 Repository。

這種方法就是需要自己創(chuàng)建一個(gè)接口,和對(duì)應(yīng)的接口實(shí)現(xiàn)類(lèi),若需要用到特殊化的實(shí)現(xiàn)方法的話,***Respository 只需要繼承你自定義的接口即可,主要有兩種能力:

  • 實(shí)現(xiàn)自定義接口
  • 可以直接覆蓋 Spring Data JPA 給我們提供的默認(rèn) ***Respository 的接口里面的方法。

案例1:單個(gè)私有的 Repository 接口實(shí)現(xiàn)類(lèi)

(1)創(chuàng)建自定義接口

/*** @author jack*/ public interface UserRepositoryCustom {/*** 自定義一個(gè)查詢方法,name的like查詢,此處僅僅是演示例子,實(shí)際中直接用QueryMethod即可* @param firstName* @return*/List<User> customerMethodNamesLike(String firstName); }

(2)自定義存儲(chǔ)庫(kù)功能的實(shí)現(xiàn)

/*** 用@Repository 將此實(shí)現(xiàn)交個(gè)Spring bean加載* 咱們模仿SimpleJpaRepository 默認(rèn)將所有方法都開(kāi)啟一個(gè)事務(wù)*/ @Repository @Transactional(readOnly = true) public class UserRepositoryCustomImpl implements UserRepositoryCustom {@PersistenceContextEntityManager entityManager;/*** 自定義一個(gè)查詢firstname的方法* @param firstName* @return*/@Overridepublic List<User> customerMethodNamesLike(String firstName) {Query query = entityManager.createNativeQuery("SELECT u.* FROM user as u " +"WHERE u.name LIKE ?", User.class);query.setParameter(1, firstName + "%");return query.getResultList();} }

我們這里采用 entityManager,當(dāng)然了也不排除自己通過(guò)最底層的 JdbcTemplate 來(lái)自己實(shí)現(xiàn)邏輯。

(3)由于這個(gè)接口是為 User 單獨(dú)寫(xiě)的,但是同時(shí)也可以繼承和 @Repository 的任何子類(lèi)。

/*** 使用的時(shí)候直接繼承 UserRepositoryCustom接口即可*/ public interface UserRepository extends Repository<User, Long>,UserRepositoryCustom { }

Controller 的調(diào)用方式如下:

/*** 調(diào)用我們自定義的實(shí)現(xiàn)方法** @return*/ @GetMapping(path = "/customer") @ResponseBody public Iterable<User> findCustomerMethodNamesLike() {return userRepository.customerMethodNamesLike("jack"); }

(4)其實(shí)通過(guò)上述方法我們可以實(shí)現(xiàn)多個(gè)自定義接口:

//如:我們自定義了HumanCustomerRepository, ContactCustomerRepository兩個(gè)Repository interface UserRepository extends CrudRepository<User, Long>, HumanCustomerRepository, ContactCustomerRepository {// 用的時(shí)候只需要繼承多個(gè)自定義接口即可 }

(5)覆蓋 JPA 里面的默認(rèn)實(shí)現(xiàn)方法

Spring Data JPA 的底層實(shí)現(xiàn)里面,自定義的 Repositories 的實(shí)現(xiàn)類(lèi)和方法要高于它幫我們提供的 Repositories,所以當(dāng)我們有場(chǎng)景需要覆蓋默認(rèn)實(shí)現(xiàn)的時(shí)候其 demo 如下:

//假設(shè)我們要覆蓋默認(rèn)的save方法的邏輯 interface CustomizedSave<T> {<S extends T> S save(S entity); } class CustomizedSaveImpl<T> implements CustomizedSave<T> {public <S extends T> S save(S entity) {// Your custom implementation} } //用法保持不變,如下: interface UserRepository extends CrudRepository<User, Long>, CustomizedSave<User> { } //CustomizedSave通過(guò)泛化可以被多個(gè)Repository使用 interface PersonRepository extends CrudRepository<Person, Long>, CustomizedSave<Person> { }

實(shí)際工作中應(yīng)用于邏輯刪除場(chǎng)景:

在實(shí)際工作的生產(chǎn)環(huán)境中,我們可能經(jīng)常會(huì)用到邏輯刪除,所以做法是一般自定義覆蓋 Data JPA 幫我們提供 remove 方法,然后實(shí)現(xiàn)邏輯刪除的邏輯即可。

2:公用的通用的場(chǎng)景,替代默認(rèn)的 SimpleJpaRepository 的場(chǎng)景,從架構(gòu)層面出發(fā)。

案例2:定義一個(gè)公用的 Repository 接口的實(shí)現(xiàn)類(lèi)。

通過(guò)構(gòu)造方法獲得 EntityManager,需要用到 Java 的泛化技術(shù)。當(dāng)你想將一個(gè)方法添加到所有的存儲(chǔ)庫(kù)接口時(shí),上述方法是不可行的,要將自定義行為添加到所有存儲(chǔ)庫(kù),首先添加一個(gè)中間接口來(lái)聲明共享行為。

(1)聲明定制共享行為的接口,用 @NoRepositoryBean:

//因?yàn)橐?#xff0c;所以必須要通用,不能失去本身的Spring Data JPA給我們提供的默認(rèn)方法,所有我們繼承相關(guān)的Repository類(lèi) @NoRepositoryBean public interface MyRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {void sharedCustomMethod(ID id); }

(2)繼承 SimpleJpaRepository 擴(kuò)展自己的方法實(shí)現(xiàn)邏輯:

public class MyRepositoryImpl<T, ID extends Serializable>extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID> {private final EntityManager entityManager;public MyRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {super(entityInformation, entityManager);// Keep the EntityManager around to used from the newly introduced methods.this.entityManager = entityManager;}public void sharedCustomMethod(ID id) {// 通過(guò)entityManager實(shí)現(xiàn)自己的額外方法的實(shí)現(xiàn)邏輯。這里不多說(shuō)了} }

注意:該類(lèi)需要具有專(zhuān)門(mén)的存儲(chǔ)庫(kù)工廠實(shí)現(xiàn)使用超級(jí)類(lèi)的構(gòu)造函數(shù),如果存儲(chǔ)庫(kù)基類(lèi)有多個(gè)構(gòu)造函數(shù),則覆蓋一個(gè) EntityInformation 加上特定于存儲(chǔ)的基礎(chǔ)架構(gòu)對(duì)象(例如,一個(gè) EntityManager 或一個(gè)模板類(lèi)),也可以重寫(xiě) SimpleJpaRepository 的任何邏輯。如邏輯刪除放在這里面實(shí)現(xiàn),就不要所有的 Repository 去關(guān)心實(shí)現(xiàn)哪個(gè)接口了。

(3)使用 JavaConfig 配置自定義 MyRepositoryImpl 作為其他接口的動(dòng)態(tài)代理的實(shí)現(xiàn)基類(lèi)。

具有全局的性質(zhì),即使沒(méi)有繼承它所有的動(dòng)態(tài)代理類(lèi)也會(huì)變成它。

@Configuration @EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class) class ApplicationConfiguration { … }

(4)使用的時(shí)候就可以顯示的選擇用哪個(gè)接口,從而選擇性的暴露 SimpleJpaRepository 的實(shí)現(xiàn)方法。

現(xiàn)在,各個(gè)存儲(chǔ)庫(kù)接口將擴(kuò)展此中間接口,而不是擴(kuò)展 Repository 接口以包含聲明的功能。接下來(lái),創(chuàng)建擴(kuò)展了持久性技術(shù)特定的存儲(chǔ)庫(kù)基類(lèi)的中間接口的實(shí)現(xiàn)。然后,該類(lèi)將用作存儲(chǔ)庫(kù)代理的自定義基類(lèi)。

//如果你要使用你自定義的全局MyRepositoryImpl只需要繼承接口即可,如下: interface PersonRepository extends MyRepositoryImpl<Person, Long>{ }

總結(jié)

以上是生活随笔為你收集整理的Spring Data JPA 从入门到精通~自定义实现Repository的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。