自定义我们自己的Specification实现类
实现
Root:查询的根对象(查询的任何属性都可以从根对象中获取)
CriteriaQuery:顶层查询对象,自定义查询方式(了解:一般不用)
CriteriaBuilder:查询的构造器,封装了很多的查询条件
Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3);//封装查询条件
代码实例
package com.cedric.test;import com.cedric.dao.CustomerDao;import com.cedric.domain.Customer;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.data.domain.Pageable;import org.springframework.data.domain.Sort;import org.springframework.data.jpa.domain.Specification;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.persistence.criteria.*;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:applicationContext.xml")public class SpecTest {@Autowiredprivate CustomerDao customerDao;/*** 根据条件,查询单个对象*/@Testpublic void testSpec(){/*** 自定义查询条件* 1.实现Specification接口(提供泛型,查询的对象类型)* 2.实现toPredicate方法(构造查询条件)* 3.需要借助方法参数中的两个参数(* root:获取需要查询的对象属性* CriteriaBuilder:构造查询条件的内部封装了很多查询条件(模糊匹配,精准匹配)* )** 案例:根据客户名称查询,查询客户名为京东的客户* 查询条件* 1.查询方式* cb对象* 2.比较的属性名称* root对象*/Specification<Customer> spec = new Specification<Customer>() {@Overridepublic Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {// 1.获取比较的属性Path<Object> custName = root.get("custName");// 2.构造查询条件 : select * from cst_customer where cust_name = '京东'/*** 第一个参数:需要比较的属性(path对象)* 第二个参数:当前需要比较的取值*/Predicate predicate = criteriaBuilder.equal(custName, "京东");//进行精准匹配(比较的属性,比较的属性取值)return predicate;}};Customer customer = customerDao.findOne(spec);System.out.println(customer);}/*** 多条件查询* 案例:根据客户名(腾讯)和客户所属行业查询(网游)*/@Testpublic void testSpec1(){/*** root:获取属性* 客户名* 所属行业* criteriaBuilder:构造查询* 1.构造客户名的精准匹配查询* 2.构造所属行业的精准匹配查询* 3.将以上两个查询联系起来*/Specification<Customer> spec = new Specification<Customer>() {@Overridepublic Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {Path<Object> custName = root.get("custName");//客户名Path<Object> custIndustry = root.get("custIndustry");//所属行业//构造函数//1.构造客户名的精准匹配查询Predicate predicate = criteriaBuilder.equal(custName, "腾讯");// 第一个参数,path(属性),第二个参数,属性的取值//2.构造所属行业的精准匹配查询Predicate predicate1 = criteriaBuilder.equal(custIndustry, "网游");//3.将多个查询条件组合到一起:组合(满足条件一并且满足条件二:与关系,满足条件一或满足条件二即可:或关系)Predicate and = criteriaBuilder.and(predicate, predicate1);//以与的形式拼接多个查询条件//criteriaBuilder.or();//以或的形式拼接多个查询条件return and;}};Customer customer = customerDao.findOne(spec);System.out.println(customer);}/*** 案例:完美根据客户名称的模糊匹配,返回客户列表* 客户名称以‘阿里’开头* equal:直接得到path对象(属性),然后进行比较即可* gt,lt,ge,le,like:得到path对象,根据path指定比较的参数类型,再去进行比较* 指定参数类型:path.as(类型的字节码对象)*/@Testpublic void testSpec3(){//构造查询条件Specification<Customer> spec = new Specification<Customer>() {@Overridepublic Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {//查询属性:用户名Path<Object> custName = root.get("custName");//查询方式:模糊匹配Predicate like = criteriaBuilder.like(custName.as(String.class), "阿里%");return like;}};/* ListCustomer> all = customerDao.findAll(spec);for(Customer customer : all){System.out.println(customer);}*///添加排序//创建排序对象,需要调用构造方法实例化sort对象//第一个参数:排序的顺序(倒序,正序)//Sort.Direction.DESC:倒序//Sort.Direction.ASC:升序//第二个参数:排序的属性名称Sort sort = new Sort(Sort.Direction.DESC,"custId");List<Customer> all = customerDao.findAll(spec, sort);for(Customer customer : all){System.out.println(customer);}}/*** 分页查询* Specification:查询条件* Pageable:分页参数* 分页参数:查询的页码,每页查询的条数* findAll(Specification,Pageable):带有条件的分页* findAll(Pageable):没有条件的分页* 返回:Page(SpringDataJpa为我们封装好的pageBean对象,数据列表,总条数)*/@Testpublic void testSpec4(){Specification spec = null;//PageRequest对象是Pageable接口的实现类/*** 创建PageRequest的过程中,需要调用他的构造方法传入两个参数* 第一个参数:当前查询的页数(从0开始)* 第二个参数:每页查询的数量*/Pageable pageable = new PageRequest(0,2);// 分页查询Page<Customer> page = customerDao.findAll(null, pageable);System.out.println(page.getContent());//得到数据集合列表System.out.println(page.getTotalElements());//得到总条数System.out.println(page.getTotalPages());//得到总页数}}
