Specification是在JPA进行查询动态拼接查询条件的,需要重写其中的Predicate方法来达到我们自己需要的功能。
@Override
public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
}
对方法中的参数做一些简单的说明:
- root:根对象,就是要把条件封装到那个对象中,如where 类名 = label.getId
- query:封装的查询关键字,比如group by等等
- criteriaBuilder:用来封装对象的,如果直接返回null,表示不需要任何条件
在查询的时候往往传过来的是一些集合等,这样就可能出现传过来的是空字段,因此在构建查询条件时需要判断是否为空。。
@Override
public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
if (label.getLabelname() != null && !"".equals(label.getLabelname())) {
Predicate predicate = criteriaBuilder.like(root.get("labelname").as(String.class), "%" + label.getLabelname() + "%");
list.add(predicate);
}
if (label.getState() != null && !"".equals(label.getState())) {
Predicate predicate = criteriaBuilder.like(root.get("state").as(String.class), label.getState());
list.add(predicate);
}
//使用数组作为最终返回值的条件
Predicate[] predicates = new Predicate[list.size()];
//将集合转换成数组
predicates = list.toArray(predicates);
//合并条件
return criteriaBuilder.and(predicates);
}
- as:指定从root中获取的对象的属性
- and:用来合并所有查询条件
- or:将所有查询条件取并集
下面来看一个分页查询的简单例子:
/**
* 分页查询
*/
public Page<Label> pageQuery(Label label, int page, int size) {
Pageable pageable = PageRequest.of(page - 1, size);
return labelDao.findAll(new Specification<Label>() {
//使用集合存放条件
List<Predicate> list = new ArrayList<>();
@Override
public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
if (label.getLabelname() != null && !"".equals(label.getLabelname())) {
Predicate predicate = criteriaBuilder.like(root.get("labelname").as(String.class), "%" + label.getLabelname() + "%");
list.add(predicate);
}
if (label.getState() != null && !"".equals(label.getState())) {
Predicate predicate = criteriaBuilder.like(root.get("state").as(String.class), label.getState());
list.add(predicate);
}
//使用数组作为最终返回值的条件
Predicate[] predicates = new Predicate[list.size()];
//将集合转换成数组
predicates = list.toArray(predicates);
//合并条件
return criteriaBuilder.and(predicates);
}
}, pageable);
}