jpa之org.springframework.data.jpa.domain.Specification
阿新 • • 發佈:2020-09-01
Specification
interface TaskRepository extends JpaRepository<Task, Integer>, JpaSpecificationExecutor<Task> /** org.springframework.data.jpa.domain.Specification Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3); #Root : 實體類引用, 獲取任何實體的屬性 #CriteriaQuery: 頂層查詢條件,自定義查詢 (where)(order by) 過濾掉關鍵字:from, where, order by等 #CriteriaBuilder: 底層查詢條件>構建查詢條件 (like,equal,and,in,greaterThanOrEqualTo,lessThanOrEqualTo) 構建條件查詢的語句 criteria 規則 criteria query 查詢規則 criteria builder 構建起規則 restriction 限制 **/
Specification五個核心方法
Optional<T> findOne(@Nullable Specification<T> var1); List<T> findAll(@Nullable Specification<T> var1); Page<T> findAll(@Nullable Specification<T> var1, Pageable var2); List<T> findAll(@Nullable Specification<T> var1, Sort var2);long count(@Nullable Specification<T> var1);
無lambda表示式
@Test public void test4(){ Specification<Task> spec = new Specification<>() { @Override public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> query, CriteriaBuilder builder) { Predicate p1= builder.equal(root.get("status"), TaskStatusEnum.CREATED); return query.where(p1).getRestriction(); } }; this.taskRepository.findAll(spec); }
有lambda表示式
@Test public void test4(){ Specification<Task> spec = (root, query, builder) -> { Predicate p1 = builder.equal(root.get("status"), TaskStatusEnum.CREATED); return query.where(p1).getRestriction(); }; this.taskRepository.findAll(spec); }
分頁查詢
@Transactional @Test public void test5(){ Specification<Task> spec = (root, query, builder) -> query.where().getRestriction(); Page<Task> pageResult = this.taskRepository.findAll(spec, PageRequest.of(0, 10)); pageResult.getContent().forEach(System.out::println); System.out.println("總頁數:" + pageResult.getTotalPages()); System.out.println("頁面記錄數:" + pageResult.getSize()); System.out.println("當前頁:" + pageResult.getNumber() + 1); System.out.println("總記錄數:" + pageResult.getTotalElements()); }
簡單order by
@Test public void test6(){ Specification<Task> spec = (root, query, builder) -> { root.fetch("owner"); //inner join user root.fetch("creator"); //inner join user root.fetch("model"); //inner join model root.fetch("client"); //inner join client Predicate p1 = builder.equal(root.get("name"), "上海福新"); //name=? Predicate p2 = builder.in(root.get("type")).value(TaskTypeEnum.BLACKOUT_APPLICATION).value(TaskTypeEnum.HIGH_USER_CHECK); //type in (?,?) Predicate p3 = builder.like(root.get("name"), "%" + "上海福新" + "%"); //name like %上海福新% return query.where(p1, p2, p3).getRestriction(); }; this.taskRepository.findAll(spec, Sort.by("name").descending()); //簡單的order by }
複雜order by
@Test public void test7(){ Specification<Task> spec = (root, query, builder) -> { root.fetch("owner"); //inner join user root.fetch("creator"); //inner join user root.fetch("model"); //inner join model root.fetch("client"); //inner join client //複雜自定義排序 List<Order> orders = new ArrayList<>(); orders.add(builder.asc( builder.selectCase() .when(builder.equal(root.get("status").as(TaskStatusEnum.class), TaskStatusEnum.CREATED), 1) .when(builder.equal(root.get("status").as(TaskStatusEnum.class), TaskStatusEnum.FINISHED), 2) .otherwise(3) )); query.orderBy(orders); Predicate p1 = builder.equal(root.get("name"), "上海福新"); //name=? Predicate p2 = builder.in(root.get("type")).value(TaskTypeEnum.BLACKOUT_APPLICATION).value(TaskTypeEnum.HIGH_USER_CHECK); //type in (?,?) Predicate p3 = builder.like(root.get("name"), "%" + "上海福新" + "%"); //name like %上海福新% return query.where(p1, p2, p3).getRestriction(); }; //this.taskRepository.findAll(spec, Sort.by("name").descending()); //簡單的order by query的排序和外面的排序同時存在時, 外面的會覆蓋裡面的排序 this.taskRepository.findAll(spec); }