之前在进行动态查询,匹配条件的时候一直不清楚对应的Predicate的查询方法和对应的规范信息,现在进行记录着重的讲一下对应的解读的方法

Specification核心方法

Predicate toPredicate(Root var1, CriteriaQuery<?> var2, CriteriaBuilder var3);

  • Root:代表查询的根对象 即实体
  • CriteriaQuery : 顶层查询对象****,用于自定义查询方式 基本不用
  • CriteriaBuilder:查询构造器,封装了很多的查询条件
 @Testpublic  void testSpecification(){//查询菜单名包含 测试 和菜单id=1212的数据Specification<SysMenu> specification=(root,query,buidler)->{//获取比较对象 从root中获取Path<String> menuName = root.get("menuName");//比较值Predicate pre1 = buidler.like(menuName, "测试%");//获取比较对象 从root中获取Path<Long> id = root.get("menuId");//比较值Predicate pre2 = buidler.equal(id, 1212l);//组装对象 使用buidlerPredicate and = buidler.or(pre1,pre2);return and;};//构建排序Sort sort=Sort.by("menuId").descending();List<SysMenu> menuList=   dao.findAll(specification,sort);menuList.forEach(p-> System.out.println(p));//分页Pageable pageable=PageRequest.of(1,1,sort);Page<SysMenu> all = dao.findAll(specification, pageable);System.out.println(all.getTotalElements());System.out.println(all.getTotalPages());System.out.println(all.getContent());}

组合多条件复杂查询

public void test(){//第一个Specification定义了两个or的equal组合Specification<Dept> s1 = (root, criteriaQuery, criteriaBuilder) -> {Predicate p1 = criteriaBuilder.equal(root.get("deptno"), "20");Predicate p2 = criteriaBuilder.equal(root.get("deptno"), "30");return criteriaBuilder.or(p1, p2);};//第二个Specification定义了两个or的like组合Specification<Dept> s2 = (root, criteriaQuery, criteriaBuilder) -> {Predicate p1 = criteriaBuilder.like(root.get("dname"), "%S%");Predicate p2 = criteriaBuilder.like(root.get("loc"), "AS%");return criteriaBuilder.or(p1, p2);};//通过Specification将两个Specification连接起来,第一个条件加where,第二个是andList<Dept> depts = deptDao.findAll(Specification.where(s1).and(s2));depts.forEach(System.out::println);}

这里面做一个小插曲,看了之前的一个list.toArray的方法对一些东西有了新的认识

  private Specification<RecommendRule> buildSpecification(String id, String ruleName, Boolean immediatelyTriggered) {return (root, query, cb) -> {List<Predicate> predicateList = new ArrayList<>();if (StringUtils.hasText(id)) {predicateList.add(cb.equal(root.get("id").as(String.class), id));}if (StringUtils.hasText(ruleName)) {predicateList.add(cb.like(root.get("ruleName").as(String.class), "%" + ruleName + "%"));}if (immediatelyTriggered != null) {predicateList.add(cb.equal(root.get("immediatelyTriggered").as(boolean.class), immediatelyTriggered));}return cb.and(predicateList.toArray(new Predicate[0]));};}

之前在toArray中对应的new Prediccate[0]中对应的返回的方法不太清楚

做力扣的每日一题时发现可以使用toArray()方法将list转为数组, 之前没怎么用过这个方法

list.toArray()方法不接收参数时, 返回一个Object数组
感觉这个不常用, 毕竟平时用到的list都指定了类型
ArrayList类中的toArray()方法源代码, 作用: 将elementData数组中的元素拷贝到长度为size的Object数组中, 并返回这个Object数组

// transient Object[] elementData; 存放list中的各个元素
// private int size; list中元素的个数
public Object[] toArray() {return Arrays.copyOf(elementData, size);
}
List<Object> list2 = new ArrayList<>();
//添加不同类型的元素, 但一般不会这么使用list...
list2.add(3);
list2.add('q');
list2.add("haha");
list2.add(new Integer(10));
Object[] objs = list2.toArray();
System.out.println(Arrays.toString(objs));
/*
打印结果
[3, q, haha, 10]
*/

toArray(T[] a)方法接收T类型的数组, 返回一个T类型的数组

public <T> T[] toArray(T[] a) {//如果传入的数组的长度小于list中的元素个数if (a.length < size)//通过Arrays.copyOf()方法进行拷贝, 内部会创建一个T类型的数组, 长度为size, 和a就没有关系了return (T[]) Arrays.copyOf(elementData, size, a.getClass());//如果传入的数组的长度大于等于list中的元素个数, 那么直接将elementData中的元素拷贝到a中System.arraycopy(elementData, 0, a, 0, size);//如果传入的数组的长度大于list中的元素个数, 将a[size]赋值为null, 这里我有疑问, 不显式赋值的话, a[size]也为null吧? 为什么要加上这句呢?if (a.length > size)a[size] = null;return a;
}

主要是对比toArray(T[] a)中a的长度和list中的元素个数size
如果a.length>=size, 那么直接调用System.arraycopy方法将elementData中的元素拷贝到a中即可
如果a.length<size, 那么需要 Arrays.copyOf方法进行拷贝, 创建一个长度为size的新数组接收elementData中的元素, 之前传入的数组a已经没用了 toArray(T[] a)的使用示例

List<String> list = new ArrayList<>();
list.add("flower");
list.add("dance");
list.add("is");
list.add("excellent");
//返回值类型和方法参数类型一致
//换句话说, 本来由list存各个String, 现在由String[]存各个String
//换句话说, 本来由list存各个String, 现在由String[]存各个String
//换句话说, 本来由list存各个String, 现在由String[]存各个String
//数组的长度指定为0或者指定为list.size()都可以. 即使传入的数组长度不够也没关系, 会创建新数组
String[] strs = list.toArray(new String[0]);
System.out.println(Arrays.toString(strs));
/*
打印结果
[flower, dance, is, excellent]
*///如果是转成以为整型数组, 得用stream(), 因为int不是引用类型, 例子:list.stream().mapToInt(k -> k).toArray()
List<int[]> list = new ArrayList<>();
list.add(new int[]{1,2});
list.add(new int[]{4,5});
list.add(new int[]{7,9});
list.add(new int[]{11,15});
//返回值类型和方法参数一样
//话句话说, 本来由list存储各个int[], 现在由int[][]存储各个int[]
//话句话说, 本来由list存储各个int[], 现在由int[][]存储各个int[]
//话句话说, 本来由list存储各个int[], 现在由int[][]存储各个int[]
//int[][]的长度指定为0或者指定为list.size()都可以.
int[][] arr = list.toArray(new int[0][]);
for(int[] t : arr){System.out.println(Arrays.toString(t));
}
/*
打印结果
[1, 2]
[4, 5]
[7, 9]
[11, 15]
*/

可以看到对应的toArray()里面添加对应的参数就可以返回指定的返回值类型, 如果不添加对应的类型,就是返回的Object方法

public class MapDemo {public static void main(String[] args) {List<Person> list = new ArrayList<>();list.add(new Person(22, "xiaohong"));list.add(new Person(33, "xiaohong2"));list.add(new Person(44, "xiaohong3"));Person[] people = list.toArray(new Person[0]);Object[] objects = list.toArray();Object[] objects6 = list.toArray();for (int i = 0; i < objects.length; i++) {System.out.println(objects[i]);}}
}class Person {int age;String name;public Person(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Person{" +"age=" + age +", name='" + name + '\'' +'}';}
}

SpringDataJPA使用Specification动态查询和分页相关推荐

  1. mybatis动态查询(分页排序搜索)+分解关联查询+Logback 日志配置(打印sql到控制台)+mybatis新增记录后返回自增的id。批量=11/2~11/20

    一.mybatis动态查询(分页排序搜索) mybatis框架分页实现,有几种方式,最简单的就是利用原生的sql关键字limit来实现,还有一种就是利用interceptor来拼接sql,实现和lim ...

  2. 使用jap的specification动态查询的演示案例与一些注意事项

    目录 学习背景与使用步骤 使用specification进行动态分页查询案例演示,包含按时间的范围查询 学习背景与使用步骤 最近在项目中遇到一个需求:对单个或者是多个条件进行分页查询(写在一个接口中) ...

  3. JSP Servlet 实现模糊动态查询并分页(拼接Sql)

    需求: 根据两个条件查询. 根据查询的结果分页,并记住查询条件. 大体流程是这样的: 第一次打开时,默认分页显示所有信息,这时候点击末页会取到最后一页数据. 当填写或选择了查询条件时,根据条件取出符合 ...

  4. Spring之Specification复杂查询和Criteria查询

    Specification官网 [一目了然]Spring Data JPA使用Specification动态构建多表查询.复杂查询及排序示例 JPA 使用 Specification 复杂查询和 Cr ...

  5. 基于SpringDataJpa的mysql动态分页多表查询

    基于SpringDataJpa的mysql动态分页多表查询 由于这篇文章预计篇幅会很长,关于Spring Data JPA的知识就简短的分享,更多的请自行度娘,JPA 封装了很多查询的接口,但今天要讲 ...

  6. SpringDataJpa (二)-动态查询多表操作

    SpringDataJpa (二)-动态查询&多表操作 一.动态查询 1.Specifications动态查询 1.1 搭建测试环境 1.1.1 导入坐标 1.1.2 创建客户实体类 1.1. ...

  7. Spring-Data-JPA 动态查询黑科技

    在开发中,用到动态查询的地方,所有的查询条件包括分页参数,都会被封装成一个查询类XxxQuery 比如说上一篇中的Item 那么ItemQuery就像这样 @Data public class Ite ...

  8. spring data jpa封装specification实现简单风格的动态查询

    github:https://github.com/peterowang/spring-data-jpa-demo 单一实体的动态查询: @Servicepublic class AdvancedUs ...

  9. SpringBoot JPA(JpaRepository)动态查询 分页展示

    大家知道Hibernate可以很轻松的根据提供条件进行动态筛选查询,那个JPA怎么实现呢,其中最为简单的就是使用Specification实现JPA的动态查询,本人也是初步接触JPA,第一次使用JPA ...

  10. SpringBoot使用SpringDataJPA通过@Query注解多对多分页查询

    文章目录 SpringBoot使用JPA@Query注解查询 1. 环境配置 2. 数据库表配置 3. 实体类配置 4. Dao代码 5. Service 代码 6. Controller 代码 7. ...

最新文章

  1. 图像标记工具Labelme和LabelImg
  2. Android 开发工具类 36_ getSimSerial
  3. mysql 读取comment_Mysql 获取表的comment 字段
  4. 基于 esp32 + lvgl8.0 的小电视
  5. 数据库基础知识——DQL语言(二)
  6. MONGODB 与sql聚合操作对应图
  7. Hive基础04、Hive建表语句详解
  8. 计算机office的好处,office2007精简版有什么优点?精简版优点介绍
  9. 光伏发电matlab模块,光伏发电的matlab仿真.docx
  10. 破解封杀ADSL路由器解决办法全面剖析
  11. c语言中指针几个字节,【C++】一个指针占几个字节?为什么呢?
  12. 程序设计——票务管理系统
  13. 西门子PLC内部的数据类型大全
  14. hdu Find Integer (6441)(大费马定理)
  15. Oracle数据库的一点
  16. 2022湖南最新中级消防员模拟考试试题及答案
  17. 面向对象编程三种特性
  18. python将str写入csv_【python3】中str转成bytes类型后用csv.writerow()写入csv文件仍然出错...
  19. 【强化学习】用强化学习通关超级马里奥!
  20. Ubuntu切换中文语言

热门文章

  1. 工商管理硕士(MBA)提前面试案例与技巧
  2. 老猿学5G随笔:RAN、RAT以及anchor移动性锚点的概念
  3. 腾讯通信云服务端使用心得,腾讯云IM
  4. 在PHP项目中使用Standford Moss代码查重系统
  5. git报错 warning: Clone succeeded, but checkout failed.
  6. 小学听课计算机笔记范文,小学听课笔记 范文大全
  7. 修改jupyter notebook的默认浏览器
  8. 算法Big O Notation
  9. linux内核贡献排名,谷歌ARM靠边站!Linux内核贡献,华为反超Intel全球第一
  10. 服务器网站怎么屏蔽ip,云服务器怎么屏蔽ip