在使用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();
- 調用entityManager.getCriteriaBuilder()來獲取CriteriaBuilder。CriteriaBuilder可以用於創建CriteriaQuery、CriteriaUpdate和CriteriaDelete。除此之外類似count、max等函數也是由CriteriaBuilder來創建的。其中Entitymanager可以使用@PersistenceContext注解來進行注入。
- 調用criteriaBuilder.createQuery來創建CriteriaQuery。其中createQuery的參數是Query返回值類型。
- 調用query.from(Order.class)。參數是對應於order表的實體類,query.from類似於sql中的from語句,該方法的執行等價於sql中的from order。
- 調用 query.select創建映射。 query.select(criteriaBuilder.count(root.get(“id”)))等價於select count(id)。如果執行query.select(root)則等價於select *。
- 使用CriteriaBuilder構造查詢條件Predicate,該predicate也就是在where后面的條件子句。
- 將Predicate放在 query.where中。
- 最后執行查詢獲取數據。
@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); }