本帖最后由 小石姐姐 于 2017-11-29 16:33 编辑
spring data jpa 通过创建方法名来做查询,只能做简单的查询,那如果我们要做复杂一些的查询呢,多条件分页怎么办,这里,spring data jpa为我们提供了JpaSpecificationExecutor接口,只要简单实现toPredicate方法就可以实现复杂的查询
1.首先让我们的接口继承于JpaSpecificationExecutor
public interface TaskDao extends JpaSpecificationExecutor<Task>{
}
2.JpaSpecificationExecutor提供了以下接口
public interface JpaSpecificationExecutor<T> {
T findOne(Specification<T> spec);
List<T> findAll(Specification<T> spec);
Page<T> findAll(Specification<T> spec, Pageable pageable);
List<T> findAll(Specification<T> spec, Sort sort);
long count(Specification<T> spec);
}
其中Specification就是需要我们传进去的参数,它是一个接口
public interface Specification<T> {
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}
3.通过重写toPredicate方法,返回一个查询 Predicate,spring data jpa会帮我们进行查询。
具体Action代码:
// 分页查询
@Action(value = "courier_pageQuery", results = { @Result(name = "success", type = "json") })
public String pageQuery() {
// 在进行有条件的查询时,需要使用Specification接口
Specification<Courier> specification = new Specification<Courier>() {
/**
* 构造条件查询方法,如果方法返回的是null,代表无条件查询 Root : 获取条件表达式(其实是查询的主表) , name=? , age = ?
* CriteriaQuery : 构造简单查询条件返回,提供where
* CriteriaBuilder : 构造Predicate对象, 条件对象, 构造复杂查询结果
*/
@Override
public Predicate toPredicate(Root<Courier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
// 因为并不知道是否所有条件都填写
List<Predicate> list = new ArrayList<>();
// 表单查询(查询当前对象对应的数据表)
// 进行快递员工号查询,判断是否为空
if (StringUtils.isNotBlank(courier.getCourierNum())) {
// 第一个参数是表达式,获取数据库中对应字段的内容. 第二个参数是前台传递过来的通过courier封装的数据
Predicate p1 = cb.equal(root.get("courierNum").as(String.class), courier.getCourierNum());
list.add(p1);
}
// 进行公司查询,模糊查询
if (StringUtils.isNotBlank(courier.getCompany())) {
Predicate p2 = cb.like(root.get("company").as(String.class), "%" + courier.getCompany() + "%");
list.add(p2);
}
// 进行快递员类型查询,等值查询
if (StringUtils.isNotBlank(courier.getType())) {
Predicate p3 = cb.equal(root.get("type").as(String.class), courier.getType());
list.add(p3);
}
// 收派标准查询,涉及多表复杂查询 模糊查询
if (courier.getStandard() != null && StringUtils.isNotBlank(courier.getStandard().getName())) {
// 使用root 主表 关联 从表 standard
Join<Object, Object> standardRoot = root.join("standard", JoinType.INNER);// 默认是内连接
Predicate p4 = cb.like(standardRoot.get("name").as(String.class),courier.getStandard().getName());
list.add(p4);
}
// 将所有的条件组装
return cb.and(list.toArray(new Predicate[0]));
}
};
Pageable pageable = new PageRequest(page - 1, rows);
Page<Courier> pageData = courierService.pageQuery(specification,pageable);
PageBean<Courier> page = new PageBean<>();
page.setTotal(pageData.getTotalElements());
page.setRows(pageData.getContent());
ActionContext.getContext().getValueStack().push(page);
return SUCCESS;
}
|
|