Spring Data JPA: 如何實(shí)現(xiàn)自定義方法

Spring Data JPA中通過(guò)Repository接口自動(dòng)實(shí)現(xiàn)了基本的ORM層操作,但在很多時(shí)候,僅僅基本的方法是不夠的。經(jīng)過(guò)對(duì)比網(wǎng)上的方法及源碼,實(shí)現(xiàn)了Repository添加自定義方法的辦法。

首先我們來(lái)添加一個(gè)自定義的接口:

添加BaseRepository接口

BaseRepository繼承了JpaRepository、JpaSpecificationExecutor,這樣可以保證所有Repository都有基本的增刪改查以及條件查詢等方法。

在BaseRepository上添加@NoRepositoryBean標(biāo)注,這樣Spring Data Jpa在啟動(dòng)時(shí)就不會(huì)去實(shí)例化BaseRepository這個(gè)接口

添加logicDelete(ID id);方法,表示該Repository的邏輯刪除功能

@NoRepositoryBean

public interface BaseRepository <T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>

{

? ? T logicDelete(ID id);

}

然后,使所有Repository接口都繼承BaseRepository


實(shí)現(xiàn)BaseRepository接口

定義好自定義的方法后,我們現(xiàn)在通過(guò)一個(gè)基本的Repository類來(lái)實(shí)現(xiàn)該方法:

首先添加BaseRepositoryImpl類,繼承SimpleJpaRepository類,使其擁有Jpa Repository的基本方法。

再實(shí)現(xiàn)logicDelete方法,其參數(shù)是領(lǐng)域?qū)ο蟮念愋?,將其和domainClass對(duì)比,如果相等,則該Repository支持該類型的領(lǐng)域?qū)ο螅?/p>

public class BaseRepositoryImpl<T, ID extends Serializable>?

? ? extends SimpleJpaRepository<T, ID>

? ? implements BaseRepository<T, ID> {

public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {

????super(entityInformation, entityManager);

}

public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {

????this(JpaEntityInformationSupport.getEntityInformation(domainClass, em), em);

}

private void setDeleteStatus(T entity) {

????????setStatus(entity, Dictionary.BUSINESS_STATUS_DELETE);

}

@Override

@Transactional(rollbackFor = Throwable.class)

public T logicDelete(ID id) {

????????T entity = findOne(id);

????????setDeleteStatus(entity);

????????return save(entity);

}

}

創(chuàng)建自定義RepositoryFactoryBean

接下來(lái)我們來(lái)創(chuàng)建一個(gè)自定義的RepositoryFactoryBean來(lái)代替默認(rèn)的RepositoryFactoryBean。RepositoryFactoryBean負(fù)責(zé)返回一個(gè)RepositoryFactory,Spring Data Jpa 將使用RepositoryFactory來(lái)創(chuàng)建Repository具體實(shí)現(xiàn),這里我們用BaseRepositoryImpl代替SimpleJpaRepository作為Repository接口的實(shí)現(xiàn)。這樣我們就能夠達(dá)到為所有Repository添加自定義方法的目的。

public class BaseRepositoryFactoryBean, T, I extends Serializable>

? ? extends JpaRepositoryFactoryBean {

? ? @Override

? ? protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {

? ? ? ? return new MyRepositoryFactory(em);

? ? }

? ? private static class MyRepositoryFactory extends JpaRepositoryFactory {

? ? ? ? private final EntityManager em;

? ? ? ? public MyRepositoryFactory(EntityManager em) {

? ? ? ? ? ? super(em);

? ? ? ? ? ? this.em = em;

? ? ? ? }

? ? ? ? @Override

? ? ? ? protected Object getTargetRepository(RepositoryInformation information) {

? ? ? ? ? ? return new BaseRepositoryImpl((Class) information.getDomainType(), em);

? ? ? ? }

? ? ? ? @Override

? ? ? ? protected Class getRepositoryBaseClass(RepositoryMetadata metadata) {

? ? ? ? ? ? return BaseRepositoryImpl.class;

? ? ? ? }

? ? }

}

配置Jpa factory class

最后,我們需要配置Jpa使用我們自定義的BaseRepositoryFactoryBean。Spring支持使用標(biāo)注進(jìn)行配置,我們?cè)赾om.xxx.Application中添加標(biāo)注@EnableJpaRepositories,repositoryFactoryBeanClass指定Repository的工廠類, basePackages用于配置掃描Repositories所在的package及子package:

@SpringBootApplication

@EnableJpaRepositories(repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class, basePackages ="com.xxx.xxx.repository")

@EnableTransactionManagement

public class Application {

? ? public static void main( String[] args ){

? ? ? ? SpringApplication.run(Application.class, args);

? ? }

}

這樣我們就為所有Repository添加了自定義的方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容