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);
}
}
}