有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在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动态查询的更多相关文章

  1. Thinkphp查询 1.查询方式 2.表达式查询 3.快捷查询 4.区间查询 5.组合查询 6.统计查询 7.动态查询 8.SQL 查询

    1.使用字符串作为条件查询 $user = M('User'); var_dump($user->where('id=1 AND user="蜡笔小新"')->sele ...

  2. Linq 动态查询排序

    Linq的排序一般是这样写的: query.OrderBy(x => x.Tel).Skip().Take(); 实际使用中排序字段可能是通过字符类型的参数来设置的,于是想这样实现: query ...

  3. ibatis动态查询条件

    ibatis的调试相对困难,出错的时候主要依据是log4生成的log文件和出错提示,这方面要能比较熟练的看懂. 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回has ...

  4. 自己写的一个关于Linq to Entity 动态查询的例子

    这两天一直想写一个动态查询的方式,先是晚上查询了一下,发现大家写的差不多都是一样的[如:http://www.cnblogs.com/ASPNET2008/archive/2012/10/28/274 ...

  5. Linq动态查询简易解决之道(原创)

    因为项目需要使用Linq来查询数据,但是在多条件查询时,需要使用一大堆if(...!=string.empty)等判断条件感觉不是很优雅.网上搜索以下,大概找到了两种办法,一种是老外写的一个类,感觉用 ...

  6. SSH动态查询封装接口介绍

    SSH动态查询封装接口介绍 1.查询记录总条数 public int count(Class c,Object[][] eq,Object[][] like,String[] group,String ...

  7. Linq to sql 实现多条件的动态查询(方法一)

    /// <summary> /// Linq to sql 多字段动态查询 /// </summary> /// <returns></returns> ...

  8. Linq to Sql : 动态构造Expression进行动态查询

    原文:Linq to Sql : 动态构造Expression进行动态查询 前一篇在介绍动态查询时,提到一个问题:如何根据用户的输入条件,动态构造这个过滤条件表达式呢?Expression<Fu ...

  9. Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询

    原文:Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询 如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时候, ...

随机推荐

  1. 2019 USP Try-outs 练习赛

    // 好久没更博客了,最近打了很多场练习赛&校内PK赛,大概自闭忙于补题吧 // 9.26 周四练习赛 A. Kolkhozy 题意 有 n 个数 \(f[i]\) ,有 q 次询问(l, r ...

  2. Python匹马行天下之python之父

    龟叔和他的python 经过了漫长的旅程,终于要看到主角Python了.Python是现在非常非常流行的编程语言,在我们能看到的大部分编程语言排行榜中,Python都能在前三甲中拥有一席之地 ,并且发 ...

  3. USACO 2004 Open The Cow Lineup /// oj25965

    题目大意: 输入n k,n头牛 k个品种 接下来n行描述每头牛的品种 输出无法找出的最短子序列的长度 Sample Input 14 515325134425123 Sample Output 3 H ...

  4. Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR tensorflow-1.13.1和1.14windows版本目前不支持CUDA10.0

    报错出现 Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR tensorflow-1.13.1和1.14windows版本目前不支持 ...

  5. Java oop第05章_多态、接口

    一. 为什么需要接口? Java中当一个类继承父类时,最多也只能继承一个父类,扩展性会受到一定的限制,为了弥补这一缺陷,Java又提供了一种新的引用数据类型分类,叫接口. 一个类只能继承一个父类,但可 ...

  6. 【FHQ-Treap】P4146 序列终结者

    题意: 给定一个序列,支持区间加,区间反转,区间max询问 裸的平衡树题,这里采用FHQ-Treap 每个节点多记录一个max值和两个lazy_tag,暴力Push_Down即可(大常数选手) 打完这 ...

  7. AM8互联设置方法

    Am8互联设置 这个只需要部署在一个总部的AM8的 Oiorg所在机器上就可以 环境: Windows 2012 or windows 2008,IIS ,.Net4 AM8 数据库必须升级到:201 ...

  8. leetcode-219-存在重复元素②

    题目描述: 第一次提交:超时 class Solution: def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool ...

  9. Linux命令速查手册(第2版)学习

    第1章.需要了解的命令行相关事项 表1-1 如何在文件名字符中使用特殊字符 字符 建议 / 绝不使用.不能转义 \ 必须转义.避免使用 _ 绝不能作为文件或目录名的第一个字符 [] 必须转义.避免使用 ...

  10. HTML5能取代Android和iOS应用程序吗?

    大量新生移动设备的兴起,改变了互联网的未来.在技术的发展上,HTML5会取代App应用吗?或者说能够在多大程度上取代呢?在HTML5规范中,已经加入了相机.磁力罗盘.GPS信息的支持.很多新兴浏览器也 ...