SpringData_03_Specifications动态查询
有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。
1.对于JpaSpecificationExecutor,这个接口基本是围绕着Specification接口来定义的。我们可以简单的理解为,Specification构造的就是查询条件。
Specification接口中只定义了如下一个方法:
- //构造查询条件
- /**
- * root :Root接口,代表查询的根对象,可以通过root获取实体中的属性
- * query :代表一个顶层查询对象,用来自定义查询
- * cb :用来构建查询,此对象里有很多条件方法
- **/
- public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
1.通过单个条件查询对象
- /**
- * 根据条件查询单个对象
- */
- @Test
- public void testFindOne() {
- //匿名内部类
- /**
- * 自定义查询条件
- * 1.实现Specification接口(提供泛型:查询的对象类型)
- * 2.实现toPredicate方法(构造查询条件)
- * 3.需要借助方法参数中的两个参数(
- * root:获取需要查询的对象属性
- * CriteriaBuilder:构造查询条件的,内部封装了很多的查询条件(模糊匹配,精准匹配)
- * )
- * 案例:根据客户名称查询,查询客户名为传智播客的客户
- * 查询条件
- * 1.查询方式
- * cb对象
- * 2.比较的属性名称 实体类名称
- * root对象
- *
- */
- Specification<Customer> spec = new Specification<Customer>() {
- @Override
- public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
- //1.获取比较的属性
- Path<Object> custName = root.get("custName");
- //2.构造查询条件 : select * from cst_customer where cust_name = 'hdh'
- Predicate predicate = cb.equal(custName, "hdh");//进行精准的匹配 (比较的属性,比较的属性的取值)
- return predicate;
- }
- };
- Customer customer = customerSpecDao.findOne(spec);
- System.out.println(customer);
- }
2.通过多个字段条件查询对象
- /**
- * 多条件查询
- * 案例:根据客户名(传智播客)和客户所属行业查询(it教育)
- *
- */
- @Test
- public void testSpec1() {
- /**
- * root:获取属性 实体类名称
- * 客户名
- * 所属行业
- * cb:构造查询
- * 1.构造客户名的精准匹配查询
- * 2.构造所属行业的精准匹配查询
- * 3.将以上两个查询联系起来
- */
- Specification<Customer> spec = new Specification<Customer>() {
- @Override
- public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
- Path<Object> p1 = root.get("custName");
- Path<Object> p2 = root.get("custIndustry");
- Predicate custName = cb.equal(p1, "hdh");
- Predicate custIndustry = cb.equal(p2, "it");
- Predicate equal = cb.and(custName, custIndustry);
- return equal;
- }
- };
- Customer customer = customerSpecDao.findOne(spec);
- System.out.println(customer);
- }
3.模糊排序查询
- /**
- * 案例:完成根据客户名称的模糊匹配,返回客户列表
- * 客户名称以 ’h‘ 开头
- *
- * equal :直接的到path对象(属性),然后进行比较即可
- * gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较
- * 指定参数类型:path.as(类型的字节码对象)
- */
- @Test
- public void testSpec3() {
- //构造查询条件
- Specification<Customer> spec = new Specification<Customer>() {
- @Override
- public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
- //查询属性:客户名
- Path<Object> custName = root.get("custName");
- //查询方式:模糊匹配
- Predicate like = cb.like(custName.as(String.class), "h%");
- return like;
- }
- };
- // List<Customer> list = customerDao.findAll(spec);
- // for (Customer customer : list) {
- // System.out.println(customer);
- // }
- //添加排序
- //创建排序对象,需要调用构造方法实例化sort对象
- //第一个参数:排序的顺序(倒序,正序)
- // Sort.Direction.DESC:倒序
- // Sort.Direction.ASC : 升序
- //第二个参数:排序的属性名称
- Sort sort = new Sort(Sort.Direction.DESC,"custId");
- List<Customer> list = customerSpecDao.findAll(spec, sort);
- for (Customer customer : list) {
- System.out.println(customer);
- }
- }
4.分页查询
- /**
- * 分页查询
- * Specification: 查询条件
- * Pageable:分页参数
- * 分页参数:查询的页码,每页查询的条数
- * findAll(Specification,Pageable):带有条件的分页
- * findAll(Pageable):没有条件的分页
- * 返回:Page(springDataJpa为我们封装好的pageBean对象,数据列表,共条数)
- */
- @Test
- public void testSpec4() {
- Specification spec = null;
- //PageRequest对象是Pageable接口的实现类
- /**
- * 创建PageRequest的过程中,需要调用他的构造方法传入两个参数
- * 第一个参数:当前查询的页数(从0开始)
- * 第二个参数:每页查询的数量
- */
- Pageable pageable = new PageRequest(0,2);
- //分页查询
- Page<Customer> page = customerSpecDao.findAll(null, pageable);
- System.out.println(page.getContent()); //得到当前页数据集合
- System.out.println(page.getTotalElements());//得到总条数
- System.out.println(page.getTotalPages());//得到总页数
- }
SpringData_03_Specifications动态查询的更多相关文章
- Thinkphp查询 1.查询方式 2.表达式查询 3.快捷查询 4.区间查询 5.组合查询 6.统计查询 7.动态查询 8.SQL 查询
1.使用字符串作为条件查询 $user = M('User'); var_dump($user->where('id=1 AND user="蜡笔小新"')->sele ...
- Linq 动态查询排序
Linq的排序一般是这样写的: query.OrderBy(x => x.Tel).Skip().Take(); 实际使用中排序字段可能是通过字符类型的参数来设置的,于是想这样实现: query ...
- ibatis动态查询条件
ibatis的调试相对困难,出错的时候主要依据是log4生成的log文件和出错提示,这方面要能比较熟练的看懂. 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回has ...
- 自己写的一个关于Linq to Entity 动态查询的例子
这两天一直想写一个动态查询的方式,先是晚上查询了一下,发现大家写的差不多都是一样的[如:http://www.cnblogs.com/ASPNET2008/archive/2012/10/28/274 ...
- Linq动态查询简易解决之道(原创)
因为项目需要使用Linq来查询数据,但是在多条件查询时,需要使用一大堆if(...!=string.empty)等判断条件感觉不是很优雅.网上搜索以下,大概找到了两种办法,一种是老外写的一个类,感觉用 ...
- SSH动态查询封装接口介绍
SSH动态查询封装接口介绍 1.查询记录总条数 public int count(Class c,Object[][] eq,Object[][] like,String[] group,String ...
- Linq to sql 实现多条件的动态查询(方法一)
/// <summary> /// Linq to sql 多字段动态查询 /// </summary> /// <returns></returns> ...
- Linq to Sql : 动态构造Expression进行动态查询
原文:Linq to Sql : 动态构造Expression进行动态查询 前一篇在介绍动态查询时,提到一个问题:如何根据用户的输入条件,动态构造这个过滤条件表达式呢?Expression<Fu ...
- Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询
原文:Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询 如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时候, ...
随机推荐
- 新建的maven项目里没有src
百度上搜到一个网友的一句话:没筷子你就不吃饭了是吧 若有所思 自己新建一个src文件 然后, 由于已经转换,因此上图没有sources选项 然后就可以在文件中随意编写文件 如果想添加package,直 ...
- ICPC 2018 焦作区域赛
// 2019.10.7 练习赛 // 赛题来源:2018 ICPC 焦作区域赛 // CF链接:http://codeforces.com/gym/102028 A Xu Xiake in Hena ...
- unittest(2)
测试用例执行顺序 1.setUp和tearDown相关 setUp:表示前置条件,它在每一个用例执行之前必须会执行一次 setUp可以理解为我们需要自动化测试时,需要打开网页窗口,输入对 ...
- xargs - 从标准输入重建并执行命令行
总览 (SYNOPSIS) xargs [-0prtx] [-e[eof-str]] [-i[replace-str]] [-l[max-lines]] [-n max-args] [-s max-c ...
- html编写的日历
1.html (1) <html> <head> <meta http-equiv="Content-Type" content="text ...
- vue-router如何参数传递
1.我们用<router-link>标签中的to属性进行传参,需要您注意的是这里的to要进行一个绑定,写成:to 先来看一下这种传参方法的基本语法: <router-link :to ...
- es5 JSON对象
1. JSON.stringify(obj/arr) js对象(数组)转换为json对象(数组) 2. JSON.parse(json) json对象(数组)转换为js对象(数组) <!DOCT ...
- Java 多线程 - 锁的类型
https://zhuanlan.zhihu.com/p/37287566 https://www.cnblogs.com/qifengshi/p/6831055.html
- flask中abort()函数的使用
一.介绍 #从flask中导入abort from flask import abort abort()函数的作用 可以让开发者在检测到web访问错误时,立即将错误信息返回回去,返回的错误码必须是已知 ...
- vs数据库连接问题
在swagger上测试时报错:数据库连接不上 原因:在项目中修改过connectionstring,但是每次编译时本地文件中并没有更新 修改: 修改配置文件属性:不复制 —> 始终复制