拓展JpaRepository接口

1.简述

本文将简单说明拓展接口遇到的一些问题以及如何实现该拓展。

2.JpaRepository

在日常的jpa使用中,我们最常用的就是继承 JpaRepository<T,ID> ,从而实现 jpa 的基本接口应用,示例代码如下:

	@Repository
	public interface xxxxxxRepository extends JpaRepository<xxxxEntity, xxx> {}

但是如果需要拓展接口,实现更复杂的功能,那么这个就不管用啦,需要进一步的实现。随着我们的代码跟踪,我们发现,JpaRepository 仅仅是接口,往后有着更加复杂的实现类,那就是SimpleJpaRepository<T, ID> ,里边有着大量可用的实现类,可以大大方便我们自己的拓展,后续我就会用到。

3.创建类和继承存储库工厂

为什么要创建存储库工厂呢,如果只是简单的写接口,你会发现其根本扫描不到你的写的类,因为 JpaRepository 再创建容器的时候就已经注入到容器中啦,所以我们需要跟着他们一起注册才能使用,示例代码如下:

//自定义BaseRepositoryFactoryBean,继承JpaRepositoryFactoryBean
public class BaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {

	public BaseRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
		super(repositoryInterface);
	}

	//重写createRepositoryFactory方法,用当前的CustomRepositoryFactory创建实例
	@Override
	protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
		return new CustomRepositoryFactory(entityManager);
	}

	//创建内部类CustomRepositoryFactory,并继承JpaRepositoryFactory
	private static class CustomRepositoryFactory<T, ID extends Serializable> extends JpaRepositoryFactory {

		public CustomRepositoryFactory(EntityManager entityManager) {
			super(entityManager);
		}

		//重写getTargetRepository方法,获得当前自定义的Repository实现
		@Override
		protected SimpleJpaRepository<?, ?> getTargetRepository(RepositoryInformation information, EntityManager entityManager) {
			return new xxxxxxImpl<T,ID>((Class<T>) information.getDomainType(), entityManager);
		}

		//重写getRepositoryBaseClass,获得当前自定义的Repository实现的类型
		@Override
		protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
			return xxxxxxImpl.class;
		}
	}
}

4.启用 jpa 存储库的注解

实现上述的代码之后,就可以开启注解啦

@EnableJpaRepositories(repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class)
public class RcsApplication {}

5.实现 jpa 的拓展类

既然已经完成上诉 3 中的流程创建,那么我就可以开始编写其中引用的类啦

  • 实现类方法如下
public class xxxxImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements xxxx<T, ID> {

	final Logger logger = LoggerFactory.getLogger(xxxxImpl.class);

	public xxxxImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
		super(entityInformation, entityManager);
	}

	public xxxxImpl(Class<T> domainClass, EntityManager em) {
		super(domainClass, em);
	}


	/**
	 * 定义复杂查询的jpa
	 * @param t 泛型
	 * @param pageable 分页
	 * @return 返回查询的分页数据
	 */
	@Override
	public Page<T> find(T t, Pageable pageable) {
	}
}

  • 接口
@NoRepositoryBean
public interface xxxx<G, ID extends Serializable> extends JpaRepository<G, ID>, JpaSpecificationExecutor<G> {
	Page<G> find(G t, Pageable pageable);
}
  • 遇到的问题
    当我不继承 JpaRepository 的话,还是会报无法找到接口类的问题,如果有知道什么原因的,可以和我说一下。

6.使用接口

只需在 jpa 中继承就可以啦

@Repository
public interface TestRepository extends xxxx<TestEntity, Long> {
	@Override
	Page<TestEntity> find(TestEntity t, Pageable pageable);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值