ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### 一.`JpaSpecificationExecutor` 方法列表 ~~~ 第一 Specifications动态查询 JpaSpecificationExecutor 方法列表 //查询单个对象 Optional<T> findOne(@Nullable Specification<T> var1); //查询列表 List<T> findAll(@Nullable Specification<T> var1); //查询全部,分页 //Pageable 分页参数 //返回值: 分页pageBean(page:是springdatajpa提供) Page<T> findAll(@Nullable Specification<T> var1, Pageable var2); //查询列表 //sort : 排序参数 List<T> findAll(@Nullable Specification<T> var1, Sort var2); //统计查询 long count(@Nullable Specification<T> var1); ~~~ ***** ### 二.dao层 ~~~ package net.youworker.repository; import net.youworker.domain.Customer; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; /** * 符合 SpringDataJpa的dao层接口规范 * JpaRepository<操作的实体类类型,实体类中主键属性的类型> * 封装了基本的CRUD操作 * JpaSpecificationExecutor<操作的实体类类型> * 封装了复杂查询(如分页等) * * @author: hcf * @qq: 46914685 * @email: 46914685@qq.com * @date: 2020-01-07 10:47 */ public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> { } ~~~ ***** ### 三.测试 ~~~ package net.youworker.domain; import net.youworker.repository.CustomerDao; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; 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.junit4.SpringRunner; import javax.persistence.criteria.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; @RunWith(SpringRunner.class) @SpringBootTest public class SpecTest { @Autowired private CustomerDao customerDao; /** * 根据条件,查询单个对象 */ @Test public void testSpec() { //匿名内部类 /** * 自定义查询条件: * 1.实现Specification接口(提供泛型:查询的对象类型) * 2.实现 toPredicate方法(构造查询条件) * 3.需要借助方法参数中的两个参数( * root: 获取需要查询的对象属性 * CriteriaBuilder: 构造查询条件,内部封装了很多的查询条件(模糊匹配,精准匹配) * ) * 例子: 根据客户名称查询 * 查询条件: * 1.查询方式 * cb对象 * 2.比较的属性名称 * root对象 * */ Specification<Customer> specification = new Specification<Customer>() { @Override public 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; } }; // Optional<Customer> customer = customerDao.findOne(specification); // System.out.println(customer.get()); List<Customer> customerList = customerDao.findAll(specification); for (Customer customer : customerList) { System.out.println(customer.getCustName()); } } /** * 多条件查询 * 例子: 根据客户名和客户所属行业查询 */ @Test public void testSpecMoreConditon() { /** * root:获取属性 * 客户名 * 所属行业 * cb:构造查询 * 1.构造客户的精准匹配查询 * 2.构造所属行业的精准匹配查询 * 3.将以上两个查询联系起来 */ Specification<Customer> specification = new Specification<Customer>() { @Override public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.获取比较的属性 Path<Object> custName = root.get("custName"); Path<Object> custIndustry = root.get("custIndustry"); //2.构造查询条件 : //1.构造客户名的精准匹配查询 Predicate predicate1 = criteriaBuilder.equal(custName, "大脚"); //2.构造所属行业的精准匹配查询 Predicate predicate2 = criteriaBuilder.equal(custIndustry, "本科"); //3.将多个查询条件组合到一起:组合(两个条件都满足:与关系;满足其中之一条件即可:或关系) Predicate predicate = criteriaBuilder.and(predicate1, predicate2); return predicate; } }; Optional<Customer> customer = customerDao.findOne(specification); System.out.println(customer.get()); } /** * 模糊查询 * 例子: 根据客户名查询 * equal: 直接得到path对象(属性),然后进行比较即可 * gt,lt,ge,le,like:得到path对象,根据path指定比较的参数类型,再去进行比较 * 指定参数类型:path.as(类型的字节码对象) */ @Test public void testSpecLike() { /** * root:获取属性 * 客户名 * 所属行业 * cb:构造查询 */ Specification<Customer> specification = new Specification<Customer>() { @Override public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.获取比较的属性 Path<Object> custName = root.get("custName"); //查询方式:模糊匹配 Predicate predicate = criteriaBuilder.like(custName.as(String.class), "%大脚%"); return predicate; } }; // List<Customer> customerList = customerDao.findAll(specification); //添加排序 /** * 创建排序对象,需要调用构造方法实例化sort对象 * 第一个参数:排序的顺序(倒序,正序) * * */ //单个排序 // Sort.Order order = new Sort.Order(Sort.Direction.DESC, "custId"); //多个排序 List<Sort.Order> orderList = new ArrayList<>(); Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "custId"); Sort.Order order2 = new Sort.Order(Sort.Direction.DESC, "custLevel"); orderList.add(order1); orderList.add(order2); List<Customer> customerList = customerDao.findAll(specification, Sort.by(orderList)); for (Customer customer : customerList) { System.out.println(customer.getCustId()); System.out.println(customer.getCustName()); } } /** * 分页查询 * Specification: 查询条件 * Pageable:分页参数 * 分页参数:查询的页码,每页查询的条数 * findAll(Specification,Pageable):带有条件的分页 * findAll(Pageable):没有条件的分页 * <p> * 返回: Page(springDataJpa为我们封装好的pageBean对象,数据列表,总条数) */ @Test public void testPage() { Specification<Customer> specification = new Specification<Customer>() { @Override public 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; } }; //排序 List<Sort.Order> orderList = new ArrayList<>(); Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "custId"); orderList.add(order1); //分页+排序 Pageable pageRequest = PageRequest.of(0, 1, Sort.by(orderList)); Page<Customer> customerPage = customerDao.findAll(specification, pageRequest); System.out.println("数据集合"); System.out.println(customerPage.getContent());//得到数据集合列表 System.out.println("总条数"); System.out.println(customerPage.getTotalElements());//得到总条数 System.out.println("总页数"); System.out.println(customerPage.getTotalPages());//得到总页面 System.out.println("每页显示数"); System.out.println(customerPage.getSize());//得到每页显示的数 System.out.println("-------------------"); for (Customer customer : customerPage.getContent()) { System.out.println(customer.getCustId()); System.out.println(customer.getCustName()); } } } ~~~