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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Data JPA: 实现自定义Repository

發布時間:2025/3/8 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Data JPA: 实现自定义Repository 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

  由于項目中的 實體(entity)默認都是繼承一個父類(包含一些公共的屬性,比如創建時間,修改時間,是否刪除,主鍵id)。為了實現邏輯刪除,一般會自己實現RepositoryFactoryBean 和?Repository。但是由于多個團隊開發的結果,表的結構沒有同一,也就是會出現有的表沒有基礎父類對應的字段,這樣就會導致自定義的jpa repository操作這些表就會出錯。

二、最開始實現

  默認父類

import java.io.Serializable; import java.sql.Timestamp;import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.MappedSuperclass;import org.hibernate.annotations.GenericGenerator;@MappedSuperclass public abstract class AbsIdEntity implements Serializable {private static final long serialVersionUID = 7988377299341530426L;@Id@GenericGenerator(name="uuid", strategy="uuid")@GeneratedValue(generator="uuid")@Column(name="id")protected String id;@Column(name = "creationtime")protected Timestamp creationTimestamp = new Timestamp(System.currentTimeMillis());@Column(name = "lastmodifiedtime")protected Timestamp modificationTimestamp = new Timestamp(System.currentTimeMillis());@Column(name = "dr")protected int dr;// 是否刪除。0:未刪除;1:已刪除/*** 主鍵,對應id字段*/public String getId() { return id; }public void setId(String id) { this.id = id; }/*** 創建日期,對應ts_insert字段*/public Timestamp getCreationTimestamp() { return creationTimestamp; }public void setCreationTimestamp(Timestamp creationTimestamp) { this.creationTimestamp = creationTimestamp; }/*** 修改日期,對應ts_update字段*/public Timestamp getModificationTimestamp() { return modificationTimestamp; }public void setModificationTimestamp(Timestamp modificationTimestamp) { this.modificationTimestamp = modificationTimestamp; }/*** 是否刪除,對應dr字段* @return*/public int getDr() {return dr;}public void setDr(int dr) {this.dr = dr;}} View Code

  自定義Repository接口

  • 添加BaseDao接口
  • BaseDao繼承了JpaSpecificationExecutor、CrudRepository,這樣可以保證所有Repository都有基本的增刪改查以及分頁等方法。
  • 在BaseDao上添加@NoRepositoryBean標注,這樣Spring Data Jpa在啟動時就不會去實例化BaseDao這個接口
import java.io.Serializable;import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.NoRepositoryBean;/*** Data Access Object基類,已經包含了常用的增刪改查操作。<br>* 使用時只需要繼承接口,不需要實現類,spring自動通過cglib生成實現類* * @param <T>* 實體類型*/ @NoRepositoryBean public interface BaseDao<T extends AbsIdEntity> extendsCrudRepository<T, Serializable>/* JpaRepository<T, Serializable> */, JpaSpecificationExecutor<T> { } View Code

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

  實現BaseRepository

  定義好自定義的方法后,我們現在通過一個基本的Repository類來實現該方法:

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

  我們發現Repository有兩個構造函數:

  • SimpleJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager)
  • SimpleJpaRepository(Class domainClass, EntityManager em)

  這里我們實現第二個構造函數,拿到domainClass和EntityManager兩個對象。因為我們要實現的是知道某個Repository是否支持某個領域對象的類型,因此在實現構造函數時我們將domainClass的信息保留下來。

import java.io.Serializable; import java.sql.Timestamp;import javax.persistence.EntityManager;import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import org.springframework.transaction.annotation.Transactional;import com.yyjz.icop.base.dao.BaseDao;@Transactional public class BaseDaoImpl<T extends AbsIdEntity> extends SimpleJpaRepository<T, Serializable> implements BaseDao<T> {@SuppressWarnings("unused")private final EntityManager entityManager;public BaseDaoImpl(Class<T> domainClass, EntityManager entityManager) {super(domainClass, entityManager);this.entityManager = entityManager;}public BaseDaoImpl(JpaEntityInformation<T, Serializable> information, EntityManager entityManager) {super(information, entityManager);this.entityManager = entityManager;}@Overridepublic <S extends T> S save(S entity) {entity.setModificationTimestamp(new Timestamp(System.currentTimeMillis()));return super.save(entity);}/*** 只做邏輯刪除*/@Overridepublic void delete(T entity) {entity.setDr(1);save(entity);}@Overridepublic void delete(Serializable id) {T entity = findOne(id);entity.setDr(1);this.save(entity);}} View Code

  RepositoryFactoryBean 實現

  接下來我們來創建一個自定義的BaseDaoFactoryBean來代替默認的RepositoryFactoryBean。RepositoryFactoryBean負責返回一個RepositoryFactory,Spring Data Jpa 將使用RepositoryFactory來創建Repository具體實現,這里我們用BaseDaoImpl代替SimpleJpaRepository作為Repository接口的實現。這樣我們就能夠達到為所有Repository添加或修改自定義方法的目的。

import xxx.AbsIdEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.RepositoryFactorySupport;import javax.persistence.EntityManager; import java.io.Serializable;public class BaseDaoFactoryBean<R extends JpaRepository<T, Serializable>, T extends AbsIdEntity> extends JpaRepositoryFactoryBean<R, T, Serializable> {@Overrideprotected RepositoryFactorySupport createRepositoryFactory(final EntityManager entityManager) {return new JpaRepositoryFactory(entityManager) {protected SimpleJpaRepository<T, Serializable> getTargetRepository(RepositoryInformation information, EntityManager entityManager) {return new BaseDaoImpl((Class<T>) information.getDomainType(), entityManager);}@Overrideprotected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {return BaseDaoImpl.class;}};} } View Code

  jpa 配置文件

<!-- Spring Data Jpa配置 --> <jpa:repositories base-package="com.xxx"transaction-manager-ref="transactionManager"entity-manager-factory-ref="entityManagerFactory"factory-class="xxx.BaseDaoFactoryBean"><!-- 自定義RepositoryFactoryBean --> </jpa:repositories>

三、改進之后

  由于有的表沒有默認父類AbsIdEntity對應的字段,導致生成?Repository 在操作表的時候會報錯。需要修改的就是RepositoryFactoryBean的實現邏輯。對于繼承了AbsIdEntity的實體類,返回自定義的BaseRepository(也就是BaseDaoImpl),否則就返回SimpleJpaRepository。注意自定義RepositoryFactoryBean的泛型也做了修改。

import xxx.AbsIdEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.RepositoryFactorySupport;import javax.persistence.EntityManager; import java.io.Serializable;public class BaseDaoFactoryBean<R extends JpaRepository<T, Serializable>, T> extends JpaRepositoryFactoryBean<R, T, Serializable> {@Overrideprotected RepositoryFactorySupport createRepositoryFactory(final EntityManager entityManager) {return new JpaRepositoryFactory(entityManager) {protected SimpleJpaRepository<T, Serializable> getTargetRepository(RepositoryInformation information, EntityManager entityManager) {Class<T> domainClass = (Class<T>) information.getDomainType();if(AbsIdEntity.class.isAssignableFrom(domainClass)) {return new BaseDaoImpl(domainClass, entityManager);} else { return new SimpleJpaRepository(domainClass, entityManager);}}@Overrideprotected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {return metadata.getDomainType().isAssignableFrom(AbsIdEntity.class) ? BaseDaoImpl.class : SimpleJpaRepository.class;}};} } View Code

  至此,完成了適配。

?

 生活不止眼前的bug,還有詩和遠方。。。

轉載于:https://www.cnblogs.com/hujunzheng/p/6494671.html

總結

以上是生活随笔為你收集整理的Spring Data JPA: 实现自定义Repository的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。