前言:
SpringDataJpa是SpringData的子框架,在Jpa的基础上进一步进行了封装和扩展,但是依旧满足不了我们的开发需求,因为小编这里列举一下通过自定义Repository对SpringDataJpa的进行扩展,并实现三个功能,如果还需要进行扩展直接添加对应的方法即可。
好了,先放一张图片便于理解吧
通过上图可以知道,只要自定义的仓库类实现了JpaRepository,Spring就会代理这个类,完成所有的功能。
在Spring中默认使用的是SimpleJpaRepository作为自定义仓库的实现类 ,但是现在我们需要告诉Spring不要给我们创建实现类,由我们自己定义实现类,然后我们就可以在自定义的实现类中扩展实现自己的功能了。
/**
* 自定义一个Repository,它是JpaRepository的功能基础上继承增强
* 在上面添加@NoRepositoryBean标注,这样Spring Data Jpa在启动时就不会去实例化BaseRepository这个接口
* @param
* @param
*/
@NoRepositoryBean //不需要SpringDataJpa实现此接口,因为需要自己实现此接口,完成功能
public interface BaseRepository extends JpaRepository, JpaSpecificationExecutor {
//以下就是我自己扩展的功能
//根据Query对象进行查询(高级查询+分页)
Page findPageByQuery(BaseQuery baseQuery);
//根据Query对象查询(高级查询不分页)
List findByQuery(BaseQuery baseQuery);
//根据自定义jpql与对应的参数进行查询,此处使用可变参数,是因为不知道需要条件有多少
List findByJpql(String jpql,Object... values);
}
/**
* 实现父类中的三个方法
* @param
* @param
*/
public class BaseRepositoryImpl extends SimpleJpaRepository implements BaseRepository {
//注意导入的是:import javax.persistence.EntityManager;
private final EntityManager entityManager;
//必需要实现父类的这个构造器
public BaseRepositoryImpl(Class domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
@Override
public Page findPageByQuery(BaseQuery baseQuery) {
//第一步:拿到所有高级查询条件
Specification spec = baseQuery.creatSpec();
//第二步:拿到排序的值--> 获取的条件是从子类获取的
Sort sort = baseQuery.createSort();
//第三步:根据条件查询分页数据并且返回
Pageable pageable = new PageRequest(baseQuery.getJpaPage(), baseQuery.getPageSize(),sort);
Page page = super.findAll(spec, pageable);
return page;
}
@Override
public List findByQuery(BaseQuery baseQuery) {
//第一步:拿到所有高级查询条件
Specification spec = baseQuery.creatSpec();
//第二步:拿到排序的值
Sort sort = baseQuery.createSort();
//第三步:拿到数据返回
return findAll(spec, sort);
}
@Override
public List findByJpql(String jpql, Object... values) {
//第一步:创建Query对象
Query query = entityManager.createQuery(jpql);
//第二步:把值设置到Query对象中去
if (values!=null) {
for (int i = 0; i < values.length; i++) {
//因为where的?后面的参数是从1开始的
query.setParameter(i + 1, values[i]);
}
}
//第三步:返回数据
return query.getResultList();
}
}
mport org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
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 BaseRepositoryFactoryBean, S, ID extends Serializable> extends JpaRepositoryFactoryBean {
@Override
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new MyRepositoryFactory(entityManager); //注:这里创建是我们的自定义类
}
//继承JpaRepositoryFactory后,把返回的对象修改成我们自己的实现
private static class MyRepositoryFactory 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((Class)information.getDomainType(),entityManager);
}
//确定功能对象的类型
@Override
protected Class> getRepositoryBaseClass(RepositoryMetadata metadata) {
return BaseRepositoryImpl.class;
}
}
}