1. 程式人生 > 實用技巧 >jpa之org.springframework.data.jpa.domain.Specification

jpa之org.springframework.data.jpa.domain.Specification

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);
    }