Spring JPA使用CriteriaBuilder動態構造查詢


在使用Spring JPA提供的方法只能進行簡單的CRUD,如果遇到復雜的情況就需要我們動態來構建查詢條件了。這里我們來看使用CriteriaBuilder如何來構造查詢。
核心代碼:

 CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
 CriteriaQuery<Long> query = criteriaBuilder.createQuery(Long.class);
 Root<Order> root = query.from(Order.class);
 query.select(criteriaBuilder.count(root.get("id")));
 Predicate predicate = criteriaBuilder.equal(root.get("id"), 1);
 query.where(predicate);
 Long singleResult = entityManager.createQuery(query).getSingleResult();
  1. 調用entityManager.getCriteriaBuilder()來獲取CriteriaBuilder。CriteriaBuilder可以用於創建CriteriaQuery、CriteriaUpdate和CriteriaDelete。除此之外類似count、max等函數也是由CriteriaBuilder來創建的。其中Entitymanager可以使用@PersistenceContext注解來進行注入。
  2. 調用criteriaBuilder.createQuery來創建CriteriaQuery。其中createQuery的參數是Query返回值類型。
  3. 調用query.from(Order.class)。參數是對應於order表的實體類,query.from類似於sql中的from語句,該方法的執行等價於sql中的from order。
  4. 調用 query.select創建映射。 query.select(criteriaBuilder.count(root.get(“id”)))等價於select count(id)。如果執行query.select(root)則等價於select *。
  5. 使用CriteriaBuilder構造查詢條件Predicate,該predicate也就是在where后面的條件子句。
  6. 將Predicate放在 query.where中。
  7. 最后執行查詢獲取數據。
      @Autowired
        EntityManager entityManager;
        @Override
        public TableResultResponse<RiskAnalyzeRecordDto> groupByCreatDateAndDataTime(RiskAnalyzeRecordDto dto, Pageable pageable) {
            CriteriaBuilder cb = entityManager.getCriteriaBuilder();
            CriteriaQuery<Object[]> cq = cb.createQuery(Object[].class);
            Root<RiskAnalyzeRecord> root = cq.from(RiskAnalyzeRecord.class);
            Predicate whereCondition;
            if (dto.getCreatedDateStart()!=null&&dto.getCreatedDateEnd()!=null){
                whereCondition = cb.and(
                        cb.like(root.<String>get("fullId"), dto.getFullId() + "%"),
                        cb.between(root.<Date>get("createdDate"),dto.getCreatedDateStart(),dto.getCreatedDateEnd())
                );
            }else if (dto.getCreatedDateEnd()!=null){
                whereCondition = cb.and(
                        cb.like(root.<String>get("fullId"), dto.getFullId() + "%"),
                        cb.lessThanOrEqualTo(root.<Date>get("createdDate"), dto.getCreatedDateEnd())
                );
            }else if (dto.getCreatedDateStart()!=null){
                whereCondition = cb.and(
                        cb.like(root.<String>get("fullId"), dto.getFullId() + "%"),
                        cb.greaterThanOrEqualTo(root.<Date>get("createdDate"), dto.getCreatedDateStart())
                );
            }else {
                whereCondition = cb.like(root.<String>get("fullId"), dto.getFullId() + "%");
            }
            if (StringUtils.isNotBlank(dto.getDataTime())){
                whereCondition = cb.and(whereCondition,cb.equal(root.get("dataTime"),dto.getDataTime()));
            }
            if (StringUtils.isNotBlank(dto.getRiskId())){
                whereCondition = cb.and(whereCondition,cb.equal(root.get("riskId"),dto.getRiskId()));
            }
            cq.multiselect(root.get("userName"),root.get("createdDate"),root.get("dataTime"), cb.sum(
                        cb.<Integer>selectCase().when(root.<Integer>get("record").isNotNull(), root.<Integer>get("record")).otherwise(0)
             )).where(whereCondition)
             .groupBy(root.get("userName"),root.get("createdDate"),root.get("dataTime")).orderBy(new OrderImpl(root.get("createdDate"),false));
    
            TypedQuery<Object[]> query = entityManager.createQuery(cq);
            query.setFirstResult(pageable.getOffset());
            query.setMaxResults(pageable.getPageSize());
            List<Object[]> list = query.getResultList();
            CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
            Root<RiskAnalyzeRecord> root1 = countQuery.from(RiskAnalyzeRecord.class);
            countQuery.select(cb.count(root1.get("id"))).
                    where(whereCondition).
                    groupBy(root1.get("userName"),root1.get("createdDate"),root1.get("dataTime"));
            TypedQuery<Long> countTypeQuery = entityManager.createQuery(countQuery);
            int count =  countTypeQuery.getResultList().size();
            List<RiskAnalyzeRecordDto> dtoList = new ArrayList<>();
            for (Object[] object : list) {
                String userName= String.valueOf(object[0]);
                String dataTime= String.valueOf(object[2]);
                Integer record= Integer.valueOf(String.valueOf(object[3]));
                RiskAnalyzeRecordDto elem = new RiskAnalyzeRecordDto();
                elem.setUserName(userName);
                elem.setCreatedDate((Date) object[1]);
                elem.setDataTime(dataTime);
                elem.setRecord(record);
                dtoList.add(elem);
            }
    
            return new TableResultResponse(count, dtoList);
        }

     

    參考文檔:JPA分組查詢,求和,自定義查詢字段,自定義VO承接  Spring JPA使用CriteriaBuilder動態構造查詢               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM