查询窗口中可以设置很多查询条件
表单中输入的内容转为datagrid的load方法所需的查询条件向原请求地址再次提出新的查询,将结果显示在datagrid中
转换方法看代码注释
查询
JPA中带条件分页查询在下面的接口中
public interface JpaSpecificationExecutor
Page
所以
public interface CourierDao extends JpaRepository
CourierDao 要继承该接口
注意修改泛型T
Action类中使用Page
model中是提交的查询条件,pageable中是page和rows两个参数
代码如下:
@Action("courierAction_pageQuery")
public String pageQuery() throws Exception {
Pageable pageable = new PageRequest(page, rows);
Page page = courierService.pageQuery(model, pageable);
this.java2Json(page, null);
/*Map map = new HashMap<>();
map.put("total", page.getTotalElements());
map.put("rows", page.getContent());
//将快递员对象中集合属性fixedAreas排除掉(忽略该属性,最终在快递员对象不存在属性)
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[]{"fixedAreas", "company"});
String json = JSONObject.fromObject(map, jsonConfig).toString();
System.err.println(json);
ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");
ServletActionContext.getResponse().getWriter().write(json);*/
return NONE;
}
但带条件分页查询的方法需要的第一个参数类型为Specification
Page
所以代码
courierService.pageQuery(model, pageable)
在service实现类中要根据model生成Specification的对象才能调用接口中方法
return courierDao.findAll(spec , pageable);
生成对象方法如下:
public Page pageQuery(final Courier model, Pageable pageable) {
//封装查询对象Specification
Specification spec = new Specification() {
//封装查询条件: sql: select * from t_courier where 列1 = ? and|or 列2 like ?
//参数一:根实体,代表Criteria查询的根对象,Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似
//参数二:代表一个specific的顶层查询对象,它包含着查询的各个部分,比如:select 、from、where、group by、order by等
//参数三:用来构建CritiaQuery的构建器对象--产生Predicate(断言)实例工厂
public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
List list = new ArrayList<>();
//参数一:从根实体通过导航方式获取属性(表中列)
//参数二:查询值
String courierNum = model.getCourierNum();
String company = model.getCompany();
String type = model.getType();
if(StringUtils.isNotBlank(courierNum)){
//。。。。 where c_courier_num = ?
Predicate p1 = cb.equal(root.get("courierNum").as(String.class), courierNum);
list.add(p1);
}
if(StringUtils.isNotBlank(company)){
// +条件 c_company = ?
Predicate p2 = cb.equal(root.get("company").as(String.class), company);
list.add(p2);
}
if(StringUtils.isNotBlank(type)){
// +条件 c_type = ?
Predicate p3 = cb.equal(root.get("type").as(String.class), type);
list.add(p3);
}
//关联查询
Standard standard = model.getStandard();
if(standard!=null){
String standardName = standard.getName();
if(StringUtils.isNotBlank(standardName)){
//创建关联对象 :Standard 默认:JoinType.INNER内连接
Join join = root.join("standard", JoinType.INNER);
//查询关联对象中属性
Predicate p4 = cb.like(join.get("name").as(String.class), "%"+standardName+"%");
list.add(p4);
}
}
if(list.size()==0){
return null;
}
Predicate [] predicates = new Predicate[list.size()];
//将list结合中断言对象存在 数组中predicates
predicates = list.toArray(predicates);
// cb.and 相当于查询条件 使用 and 拼接--并且
// cb.or 相当于查询条件 使用 or 拼接 --或者
return cb.or(predicates);
}
};
return courierDao.findAll(spec , pageable);
}
StringUtils为….StringUtils包下工具类
其中断言的值有好几个
拼接的时候需要提供一个断言的数组
return cb.or(predicates );
而数组是定长的,我们又不确定有几个断言
所以只能创建一个可变长度的数组,那么就需要设置数组长度使用一个变量,使用list.size()
Predicate [] predicates = new Predicate[list.size()];
将集合变为指定类型的数组使用其toArray()方法,无惨转为Object[],有参转为指定类型的数组
predicates = list.toArray(predicates);
如果没有额外条件,就是一个正常的分页查询
if(list.size()==0){
return null;
}
这时
return courierDao.findAll(spec , pageable);
spec为空
如果查询条件在实体的关联对象中,则需要多表关联查询
不能直接使用root,直接使用root.get(“name”)得到的是当前实体(courier)中的name,我们要的是关联实体(standard)的name属性
所以要得到关联对象join,通过standard对象(属于Courier实体的属性即可)关联,默认是内连接,也可以左外右外连接
Join
通过关联对象进行查询即可
Predicate p4 = cb.like(join.get(“name”).as(String.class), “%”+standardName+”%”);
datagrid这个ajax请求的好处就在于发送的请求不会刷新浏览器,所以查询的条件会一直在,不会影响到分页
Original: https://www.cnblogs.com/qingyundian/p/9234556.html
Author: Advancing-Swift
Title: 序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询 多表关联查询
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/542136/
转载文章受原作者版权保护。转载请注明原作者出处!