repository层抽取父类与扩展方法(修改代理类的默认继承)

1.创建一个BaseRepostory接口

/**
 * 自定义一个Repository,它是JpaRepository的功能基础上继承增强
 * 在上面添加@NoRepositoryBean标注,这样Spring Data Jpa在启动时就不会去实例化BaseRepository这个接口
 * @param <T>
 
* @param <ID>
 
*/

@NoRepositoryBean
public interface BaseRepository<T,ID extends Serializable> extends JpaRepository<T,ID>,JpaSpecificationExecutor<T>{
   
//根据Query拿到分页对象(分页)
   
Page findPageByQuery(BaseQuery baseQuery);

   
//根据Query拿到对应的所有数据(不分页)
   
List<T> findByQuery(BaseQuery baseQuery);

   
//根据jpql与对应的参数拿到数据
    List findByJpql(String jpql,Object... values);
}

2.实现BaseRepostory接口

public class BaseRepositoryImpl<T,ID extends Serializable> extends SimpleJpaRepository<T,ID> implements BaseRepository<T,ID> {

   
private final EntityManager entityManager;

   
//必需要实现父类的这个构造器
   
public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
       
super(domainClass, em);
       
this.entityManager = em;
    }

   
@Override
   
public Page findPageByQuery(BaseQuery baseQuery) {
       
// 拿到所有高级查询条件
       
Specification specification = baseQuery.createSpecification();
       
// 拿到分页对象
       
Pageable page = baseQuery.createPage();
       
// 查询数据
       
return findAll(specification, page);
    }

   
@Override
   
public List<T> findByQuery(BaseQuery baseQuery) {
       
// 根据高级查询条件查询数据(不加分页)
       
return findAll(baseQuery.createSpecification());
    }

   
@Override
   
public List findByJpql(String jpql, Object... values) {
       
// 根据传入的jpql创建query对象
       
Query query = entityManager.createQuery(jpql);
       
for (int i = 0; i < values.length; i ++){
           
// 根据传入参数个数给jpql中的?赋值
           
query.setParameter(i + 1, values[i]);
        }
       
// 返回查询数据(List集合)
       
return query.getResultList();
    }
}

3.子接口直接继承BaseRepository就能获取扩展方法

/**
 * JpaRepository<ProductRepository,Long>:拥有CRUD、排序、分页方法
 * 泛型一:要进行CRUD的domain
 * 泛型二:domain的主键类型
 *
 * JpaSpecificationExecutor<ProductRepository>:可以将高级查询、排序、分页结合
 */
public interface ProductRepository extends BaseRepository<Product, Long> {
    @Query("select o from Product o where name = ?1")
    Product checkName(String name);
}

4.使代理类默认继承BaseRepositoryImpl

  • 实现JpaRepository接口后,jpa会自动创建一个代理类
  • 代理类默认继承SimpleJpaRepository类,SimpleJpaRepository类实现了JpaRepository接口中的所有方法
  • 此时代理类中并没有实现我们扩展的方法,所以必须修改代理类默认继承

052e155cb2ce4f033f3858b3446320888d0.jpg

步骤:

  1. BaseRepositoryImpl类继承SimpleJpaRepository类,并实现父类构造器
    b90c44808bca5910b8279b0dfffb8665e20.jpg
  2. 创建BaseRepositoryFactoryBean类(固定代码,直接使用即可)

    /**
     * BaseRepository
    接口默认实现类继承SimpleJpaRepository
     * 修改默认继承为BaseRepository
     * @param <T>
     
    * @param <S>
     
    * @param <ID>
     
    */
    public class BaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T,S,ID> {

       
    @Override
       
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
           
    return new MyRepositoryFactory<T,ID>(entityManager); //注:这里创建是我们的自定义类
        }

       
    //继承JpaRepositoryFactory后,把返回的对象修改成我们自己的实现
        private static  class MyRepositoryFactory<T,ID extends Serializable>   extends JpaRepositoryFactory {
           
    private final EntityManager entityManager;
           
    /**
             * Creates a new {@link JpaRepositoryFactory}.
             *
             * @param
    entityManager must not be {@literal null}
             */
           
    public MyRepositoryFactory(EntityManager entityManager) {
               
    super(entityManager);
               
    this.entityManager = entityManager;
            }
           
    //这里返回最后的功能对象
            @Override
           
    protected Object getTargetRepository(RepositoryInformation information) {
               
    return new BaseRepositoryImpl<T,ID>((Class<T>)information.getDomainType(),entityManager);
            }
           
    //确定功能对象的类型
            @Override
           
    protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
               
    return BaseRepositoryImpl.class;
            }
        }
    }

  3. 配置applicationContext.xml
    <!--SpringDataJpa的方案去扫描它
        只要发现接口继承了JpaRepository接口,就自动完成CRUD以及分页等功能
    -->

    <jpa:repositories base-package="cn.meco.aisell.repository"
                     
    entity-manager-factory-ref="entityManagerFactory"
                     
    transaction-manager-ref="transactionManager"
                     
    factory-class="cn.meco.aisell.repository.BaseRepositoryFactoryBean"

    />
  4. 子接口直接继承BaseRepository即可
    public interface EmployeeRepository extends BaseRepository<Employee, Long> {

转载于:https://my.oschina.net/u/4107179/blog/3030121

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值