← 返回首页
SpringBoot基础教程(十九)
发表时间:2020-10-26 12:19:18
JpaSpecificationExecutor

Spring Data Jpa 支持 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);

通过实现 Specification 中的 toPredicate 方法来定义动态查询,通过 CriteriaBuilder 来创建查询条件。

使用Criteria 查询方式实现类似StudentsRepository接口中findAllBySnameAndGender命名查询的效果。

StudentsRepository接口定义有以下命名查询方法:

public interface StudentsRepository extends JpaRepository<Students,Integer> {

    //自定义根据学生的姓名和性别查询学生集合
    List<Students> findAllBySnameAndGender(String sname,String gender);

}

实现步骤:

1.定义StudentsRepository继承自JpaSpecificationExecutor 接口。

public interface StudentsRepository extends JpaRepository<Students,Integer>,JpaSpecificationExecutor  {
    //自定义根据学生的姓名和性别查询学生集合
    List<Students> findAllBySnameAndGender(String sname,String gender);
}

2.在StudentsService层定义Criteria 查询方法。

public interface StudentsService  {

    //查询学生的姓名和性别
    List<Students> findAllBySnameAndGender(String sname,String gender);
    //使用Criteria 查询
    List<Students> findAll(Specification<Students> var1);

}

3.在StudentsServiceImpl中调用JpaSpecificationExecutor 接口的findAll方法。

@Service
public class StudentsServiceImpl implements StudentsService {
    @Resource
    private StudentsRepository studentsRepository;

    @Override
    public List<Students> findAllBySnameAndGender(String sname,String gender) {
        return studentsRepository.findAllBySnameAndGender(sname,gender);
    }

    @Override
    public List<Students> findAll(Specification<Students> var1) {
        return studentsRepository.findAll(var1);
    }
}

4.编写测试类,测试Criteria 查询。

@RunWith(SpringRunner.class)//指定Junit4使用Spring提供的测试环境
@SpringBootTest
public class StudentsServiceTest {
    @Resource
    private StudentsService studentsService;

    @Test
    public void testQueryStudentsBySnameAndGenderWithCriteria(){
        Specification<Students> criteria = new Specification<Students>(){
            @Override
            public Predicate toPredicate(Root<Students> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate p1 = criteriaBuilder.equal(root.get("sname"),"张三");
                Predicate p2 = criteriaBuilder.equal(root.get("gender"),"男");

                return criteriaBuilder.and(p1,p2);
            }
        };
        List<Students> studentsList = studentsService.findAll(criteria);
        for(Students s : studentsList){
            System.out.println(s);
        }
    }
}