6-16 动态多条件复杂查询的分页实现
本节内容:
本节内容涉及多接口继承、JpaSpecificationExecutor(此为数据仓库层 四接口之一 之前一直用的JpaRepository)、Specification三个知识点
JpaSpecificationExecutor:Spring Data Jpa同样提供了类似Hibernate的Criteria的查询方式,要使用这种方式需要继承JpaSpecificationExecutor,这个接口提供了5种方法,其中的关键就是通过Specification来定义查询条件。
Specification:用于封装JPA Criteria查询条件。
注:Hibernate的Criteria查询是指使用面向对象的方法从数据库中获取结果
JpaRepository中可以通过面向对象的方式进行查询,如findByComnameAndContactname,但条件一多、查询稍稍特殊一点,这种方式就有点反人类了。
工作开展步骤:
1)在数据仓库Repository接口中增加继承的接口JpaSpecificationExecutor;
在数据仓库层内 找到要增加的数据仓库 在原有的继承接口上 加个逗号 将JpaSpecificationExecutor 加上即可
public interface CompanyRepo extends JpaRepository<Company,String > , JpaSpecificationExecutor
2)在业务层中增加复杂查询的接口;
3)在业务层实现类中,基于Specification增加一个复杂查询的方法;
在业务层接口 加一个 public Page queryDynamic(Map<String, Object> reqMap, Pageable pageable)
实现类内加上他
@Override
public Page queryDynamic(Map<String, Object> reqMap, Pageable pageable) {
/**
* 多条件动态查询实现类
* 常用查询 :equal(等于) notEqual(不等于) gt(大于) ge(大于等于) Lt(小于) Le(小于等于) between(闭区间中的值) like(模糊)等
*/
Specification querySpecifi=new Specification() {
// 定义一个 Specification (条件集合) querySpecifi=new Specification() 他自动会帮你弹出下面的方法 需要注意的只有Company 整个实体类
// 方法一开始是空的 想怎么查询 还是要自己写
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
List predicates =new ArrayList<>();
// 条件设置部分 查询CriteriBuilder源码 查询分类
// 其中List 表示一个表格条件集合 把需要查询的条件放入
if(!reqMap.get(“comname”).toString().equals(""))//判断公司名称是否为空
{
predicates.add(cb.like(root.get(“comname”),"%"+reqMap.get(“comname”).toString()+"%"));
}
if(!reqMap.get(“comstatus”).toString().equals(“全部”))//运营状态 精确查询 此时的数据内部运营状态 无一未“全部” 此处把他当成变量 需要什么就改成什么
{
predicates.add(cb.equal(root.get(“comstatus”),reqMap.get(“comstatus”).toString()));
}
if(!reqMap.get(“employeenumber”).toString().equals(""))//查看人数是否为空
{
predicates.add(cb.gt(root.get(“employeenumber”),Integer.parseInt(reqMap.get(“employeenumber”).toString())));
// 转为整型 进行比较
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
// 生成一个集合 集合下标为条件的个数 至于cb的 CriteriaBuilder 表示准则生成器 具体按照这个用即可 为上面的new 返回值
}
};
return this.companyRepo.findAll(querySpecifi,pageable);
}
4)在控制层中新增加多条件查询分页的接口;
@RequestMapping(“listCompany”)
public String showThOne(){
return "/company/ListCompany.html";
}
上面是页面链接 下面是实现功能反馈
@PostMapping("/findAllSimplePageMap")
@ResponseBody
public String findAllSimplePageMap(@RequestBody(required=false) Map<String,Object> reqMap){
/**
* 多条件排序 及 分页查询
*/
int page=0;
int size=3;
if(reqMap!=null)
{
if(reqMap.get(“page”).toString()!=null){page=Integer.parseInt(reqMap.get(“page”).toString());}
if(reqMap.get(“size”).toString()!=null){size=Integer.parseInt(reqMap.get(“size”).toString());}
}
List<Sort.Order> orders =new ArrayList<>();
orders.add(new Sort.Order(Sort.Direction.DESC,"comname"));
orders.add(new Sort.Order(Sort.Direction.ASC,"comaddress"));
Page<Company> pageinfo =csi.findAllSimplePage(PageRequest.of(page,size,Sort.by(orders)));
List<Company> companies =pageinfo.getContent();
JSONObject result =new JSONObject();
result.put("rows",companies); //此处rows与total 都是定死的
result.put("total",pageinfo.getTotalElements());
// "rows"和"total"这两个属性是为前端列表插件 “bootstrap-table”服务的
return result.toJSONString();
// 返回JSON格式的 字符串
}
5)在公司列表页面增加查询条件表单;
//最主要的就是这一条 写个能跟一会要写的JS对应起来的ID
在下方 引入一会要写的JS 6)在公司列表JS文件中增加代码片段:a) 包括修改接口地址;b)在bootstrap-table中增加参数传递;c)给查询按钮设置事件; 以下直接复制 (以后用的时候直接用 只需要改url)
下面 $(’#tb_Company’).bootstrapTable 之内基本相当于在JS里面写属性参数 其中 //queryParamsType: ’ ’ 是设置传递方式 下方的 queryParams就是传递方式
//JQuery 的代码 我们通常会包裹在一个(function(){})也就是$(document).ready(function(){})的简写
$(function (){
// 数据列表展示
KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲tb_Company').bo…(’#tb_Company’).bootstrapTable(‘getOptions’).pageSize;
var pageNumber=$(’#tb_Company’).bootstrapTable(‘getOptions’).pageNumber;
return pageSize * (pageNumber - 1 ) + index + 1;
},
align:‘center’,
width:50
}, {
field: ‘uuid’,
title: ‘UUID’,
visible: false // 是否显示 默认显示
// 下面一般把所有的字段都写上 然后用到那个显示哪一个 不用的就先等等
},{
field: ‘comname’,
title: ‘公司名称’
},{
field: ‘comurl’,
title: ‘公司网址’
},{
field: ‘comtelephone’,
title: ‘公司座机’,
visible: false
},{
field: ‘establishdate’,
title: ‘成立日期’
},{
field: ‘employeenumber’,
title: ‘员工人数’
},{
field: ‘totaloutput’,
title: ‘总产值’,
visible: false
},{
field: ‘comdesc’,
title: ‘公司简介’,
visible: false
},{
field: ‘comstatus’,
title: ‘运营状态’
},{
field: ‘contactname’,
title: ‘联系人姓名’
},{
field: ‘comtactemail’,
title: ‘联系人邮箱’
}]
});});
说明:在业务层中实现的多条件查询方法中用到了CriteriaBuilder,这个几乎囊括了通用SQL查询中的全部功能,具体可以查看该类的方法,上面的方法通过CriteriaBuilder进行查询条件的组装,在这个复杂查询方法中CriteriaQuery参数我们没有用到,感兴趣的可以查询相关资料。
前台 :网页页面 后台 数据仓库层 业务层 控制层