jpa的JpaSpecificationExecutor使用对象自定义sql条件

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jpa的JpaSpecificationExecutor使用对象自定义sql条件相关的知识,希望对你有一定的参考价值。

Specification的使用

Spring Data Jpa同样提供了类似Hibernated 的Criteria的查询方式,要使用这种方式只要继承JpaSpecificationExecutor,该接口提供了如下一些方法

T findOne(Specification<T> var1);
List<T> findAll(Specification<T> var1);
Page<T> findAll(Specification<T> var1, Pageable var2);
List<T> findAll(Specification<T> var1, Sort var2);
long count(Specification<T> var1);

比如继承JpaSpecificationExecutor的dao层

@Repository
public interface ShopUserMiddleRepository extends JpaRepository<ShopUserMiddleDO, Long>, JpaSpecificationExecutor<ShopUserMiddleDO> {

    ShopUserMiddleDO findByUserId(Long userId);
}

该接口通过Specification来定义查询条件,很多朋友可能使用的方式都是基于SQL的,对这种方式可能不太习惯,其实就是类似mybatispluswrapper,将sql条件用对象来实现。这里先简单看一下示例。

@Test
public void testSpecificaiton() {
    List<Student> stus = studentSpecificationRepository.findAll(new Specification<Student>() {
        @Override
        public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            //root.get("address")表示获取address这个字段名称(获取实体类的属性名对应的表字段名),like表示执行like查询,%zt%表示值
            
            Predicate p1 = criteriaBuilder.like(root.get("address"), "%zt%");
            Predicate p2 = criteriaBuilder.greaterThan(root.get("id"),3);
            //将两个查询条件联合起来之后返回Predicate对象
            return criteriaBuilder.and(p1,p2);
        }
    });
    Assert.assertEquals(2,stus.size());
    Assert.assertEquals("oo",stus.get(0).getName());
}

多个Specification组合

使用Specification的要点就是CriteriaBuilder,通过这个对象来创建条件,之后返回一个Predicate对象。这个对象中就有了相应的查询需求,我们同样可以定义多个Specification,之后通过Specifications对象将其连接起来。以下是一个非常典型的应用

@Test
public void testSpecificaiton2() {
//第一个Specification定义了两个or的组合
Specification<Student> s1 = new Specification<Student>() {
    @Override
    public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
        Predicate p1 = criteriaBuilder.equal(root.get("id"),"2");
        Predicate p2 = criteriaBuilder.equal(root.get("id"),"3");
        return criteriaBuilder.or(p1,p2);
    }
};
//第二个Specification定义了两个or的组合
Specification<Student> s2 = new Specification<Student>() {
    @Override
    public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
        Predicate p1 = criteriaBuilder.like(root.get("address"),"zt%");
        Predicate p2 = criteriaBuilder.like(root.get("name"),"foo%");
        return criteriaBuilder.or(p1,p2);
    }
};
//通过Specifications将两个Specification连接起来,第一个条件加where,第二个是and
List<Student> stus = studentSpecificationRepository.findAll(Specifications.where(s1).and(s2));

    Assert.assertEquals(1,stus.size());
    Assert.assertEquals(3,stus.get(0).getId());
}

参考了大佬的博文

以上是关于jpa的JpaSpecificationExecutor使用对象自定义sql条件的主要内容,如果未能解决你的问题,请参考以下文章

JPA Hibernate jpa spring data jpa

JPA 版本混淆

Jpa使用详解

Jpa使用详解

如何从 JPA 注释的实体类生成 JPA 映射文件?

jpa/springdatajpa