查询窗口中可以设置很多查询条件

表单中输入的内容转为datagrid的load方法所需的查询条件向原请求地址再次提出新的查询,将结果显示在datagrid中

转换方法看代码注释

<td colspan="2"><a id="searchBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-search'">查询</a>
<script type="text/javascript">
$("#searchBtn").click(function(){
//1、将查询条件值获取到
var condition = $("#searchForm").serializeJson();
console.info(condition);
//2、带参提交一次查询,从服务器加载新数据 包括两种数据1、分页需要page,rows 2、查询条件
$('#grid').datagrid('load', condition);
//将查询窗口关闭
$("#searchWindow").window("close");
}) //(自定义的JQuery方法)将表单中所有有name属性的输入项使用serializeArray()方法序列化表单
//转变为 {"input的name":"input的value"} 的json对象形式,作为datagrid的load方法的查询条件
$.fn.serializeJson=function(){
var serializeObj={};
var array=this.serializeArray();
var str=this.serialize();
$(array).each(function(){
if(serializeObj[this.name]){
if($.isArray(serializeObj[this.name])){
serializeObj[this.name].push(this.value);
}else{
serializeObj[this.name]=[serializeObj[this.name],this.value];
}
}else{
serializeObj[this.name]=this.value;
}
});
return serializeObj;
};
</script>
</td>

JPA中带条件分页查询在下面的接口中

public interface JpaSpecificationExecutor<T> {

Page<T> findAll(Specification<T> spec, Pageable pageable);

所以

public interface CourierDao extends JpaRepository<Courier, Integer>, JpaSpecificationExecutor<Courier> {

CourierDao 要继承该接口

注意修改泛型T

Action类中使用Page<Courier> page = courierService.pageQuery(model, pageable);//带两个参的方法

model中是提交的查询条件,pageable中是page和rows两个参数

代码如下:

@Action("courierAction_pageQuery")
public String pageQuery() throws Exception {
Pageable pageable = new PageRequest(page, rows);
Page<Courier> page = courierService.pageQuery(model, pageable);
this.java2Json(page, null);
/*Map<String, Object> 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<T> spec 如下

Page<T> findAll(Specification<T> spec, Pageable pageable);

所以代码

courierService.pageQuery(model, pageable)

在service实现类中要根据model生成Specification的对象才能调用接口中方法

return courierDao.findAll(spec , pageable);

生成对象方法如下:

public Page<Courier> pageQuery(final Courier model, Pageable pageable) {
//封装查询对象Specification
Specification<Courier> spec = new Specification<Courier>() { //封装查询条件: 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<Courier> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> 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<Object, Object> 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为org.apache.commons.lang3.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<Object, Object> join = root.join("standard", JoinType.INNER);

通过关联对象进行查询即可

Predicate p4 = cb.like(join.get("name").as(String.class), "%"+standardName+"%");


datagrid这个ajax请求的好处就在于发送的请求不会刷新浏览器,所以查询的条件会一直在,不会影响到分页

序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询 多表关联查询的更多相关文章

  1. form表单转化json对象

    利用 $.fn 可以让每一个jquery 对象都能直接使用这个方法. //form表单转化json对象$.fn.serializeObject = function () { var o = {}; ...

  2. 将forme表单转换为Json对象

    //将Form 表单转换为Json字符串 $.fn.serializeObject = function () { var o = {}; var a = this.serializeArray(); ...

  3. jQuery序列化表单为JSON对象

    <form id="myform"> <table> <tr> <td>姓名:</td> <td> < ...

  4. (jQuery 插件)封装容器的表单为json对象

    下面代码可以把一个页面容器中的表单元素封装成一个json对象. (function($){ $.fn.serializeObject=function(){ var inputs=$(this).fi ...

  5. 【spring data jpa】带有条件的查询后分页和不带条件查询后分页实现

    一.不带有动态条件的查询 分页的实现 实例代码: controller:返回的是Page<>对象 @Controller @RequestMapping(value = "/eg ...

  6. (笔记)JQuery扩展方法实现Form表单与Json互相转换

    JQuery笔记 记两段代码,使用JQuery实现从表单获取json与后端交互,以及把后端返回的json映射到表单相应的字段上. 把表单转换出json对象 //把表单转换出json对象 $.fn.to ...

  7. SpringMVC表单或Json中日期字符串与JavaBean的Date类型的转换

    SpringMVC表单或Json中日期字符串与JavaBean的Date类型的转换 场景一:表单中的日期字符串和JavaBean的Date类型的转换 在使用SpringMVC的时候,经常会遇到表单中的 ...

  8. [转载]WebBrowser控件表单(form)的自动填写和提交

    话说有了WebBrowser类,终于不用自己手动封装SHDocVw的AxWebBrowser这个ActiveX控件了.这个类如果仅仅作为一个和IE一模一样浏览器,那就太没意思了(还不如直接用IE呢). ...

  9. Spring data jpa JavassistLazyInitializer 不仅是Json序列化问题.以及解决办法

    最近偷点时间更新一下框架,使用SpringBoot2.0 整套一起更新一下,发现些小问题 Spring data jpa getOne 返回的是代理对象,延迟加载的,ResponseBody成Json ...

随机推荐

  1. C#学习笔记5

    1.接口的显式实现:显式实现需要在实现接口的类型中,在实现接口的成员中添加接口名称的前缀.且没有必要添加public.virtual这些修饰符,因为显式实现只能通过接口调用,不能用实现类进行调用.为此 ...

  2. 1.zookeeper的安装

    1.解压zk压缩包 tar -zxvf (zk压缩包路径名) -C (解压目标目录路径) 2.在zk解压目录下新建data文件夹 mkdir data 3.在data文件夹下新建myid vi myi ...

  3. Java集合篇六:Map中key值不可重复的测试

    package com.test.collection; import java.util.HashMap; import java.util.Map; //Map中key值不可重复的测试 publi ...

  4. Python爬虫之三种数据解析方式

    一.引入 二.回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需 ...

  5. 避免console错误,console兼容

    背景:写js代码时写了很多console.log进行日志打印,最后上生产时不想删除日志输出, 但是ie在不打开控制台时,日志输出会导致后续js不执行,所以需要适时屏蔽js日志输出 (IE等不支持con ...

  6. SpagoBI 和 开源ERP(iDempiere)整合入门

    Created by 蓝色布鲁斯,QQ32876341,blog http://www.cnblogs.com/zzyan/ iDempiere官方中文wiki主页 http://wiki.idemp ...

  7. RecycleView + SwipeRefreshLayout 实现下拉刷新和底部自动加载

    前段时间项目里面使用了RecycleView 但是里面的刷新和加载都是框架里面封装好的,直接使用 这几天比较闲就自己来实现以下. 因为SwipeRefreshLayout是一个下拉刷新控件所有直接和R ...

  8. ASP.NET中引用dll“找不到指定模块"的完美解决办法 z

    DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息.DllImport属性应用于方法,要求最少要 ...

  9. Selenium2学习(十三)-- JS处理滚动条

    前言 selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了. 常见场景: 当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的. 这时候 ...

  10. MySQL的基础(优化)3

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据 ...