Spring Data Jpa高級用法

Spring Data Jpa高級用法

1、原生SQL語句查詢

@Query(value = "select count(*) from tran_problem where propose_user=?1 and review_notice_flag!=?2 and status=?3", nativeQuery=true)
Integer findCountByUserIdAndReviewNoticeFlagNum(Integer userId, Integer noticeStatusId, Integer status);

注意:

①Spring Data Jpa中不支持分組查詢

②@Query中加上nativeQuery=true使用的是原生的SQL語句查詢,如果不帶nativeQuery=true(nativeQuery默認爲false)使用的時HQL查詢,HQL查詢中不支持 * 字符

2、外鍵查詢

// 根據部門id分頁查詢該部門的用戶信息
Page<Employee> findAllByDepartment_DepartmentId(Integer departmentId, Pageable pageable);

Employee對象中的department屬性的類型是Department類型,並且在department字段是表employee的外鍵

3、EntityManager查詢

複雜的查詢可以自己寫SQL語句,並且讓返回的數據自動封裝成對象

@Repository
public class TranproblemRepositoryImpl {

    @PersistenceContext
    private EntityManager entityManager;

    /** 查詢發佈問題各個狀態問題總數 **/
    private final static String SELECT_PROPOSE_TRANBLEM_SQL = " " +
            "SELECT                                             " +
            "   status, count( * ) as count                     " +
            "FROM                                               " +
            "   tran_problem                                    " +
            "WHERE                                              " +
            "   propose_user = :userId                          " +
            "GROUP BY                                           " +
            "   status                                          ";

    // 查詢發佈問題各個狀態問題總數
    public List<TranproblemDto> selectProposeTranblem(Integer userId) {

        Query query = entityManager.createNativeQuery(SELECT_PROPOSE_TRANBLEM_SQL)
                .setParameter("userId", userId);

        // 將查詢結果與封裝成指定的對象
        query.unwrap(SQLQuery.class)
                .addScalar("status", IntegerType.INSTANCE)
                .addScalar("count", IntegerType.INSTANCE)
                .setResultTransformer(Transformers.aliasToBean(TranproblemDto.class));

        List<TranproblemDto> tranproblemDtoList = query.getResultList();

        return tranproblemDtoList;
    }
}

TranproblemDto:

public class TranproblemDto {

    /** 問題的狀態 **/
    private Integer status;

    /** 問題總數 **/
    private Integer count;
    
    // 省略get、set方法
}

4、Specification查詢

Specification常用於檢索

 /**
     * 複合查詢
     * @param searchForm
     * @param pageable
     * @return
     */
public Page<TranProblem> search(TranProblemSearchForm searchForm, Pageable pageable) {

  // 添加排序規則
  List<Order> orders = new ArrayList<>();
  Order updateTimeOrder = new Order(Direction.DESC, "updateTime");
  orders.add(updateTimeOrder);
  Order createTimeOrder = new Order(Direction.DESC, "createTime");
  orders.add(createTimeOrder);
  pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), new Sort(orders));

  return tranProblemRepository.findAll(new Specification<TranProblem>() {
    @Override
    public Predicate toPredicate(Root<TranProblem> root, CriteriaQuery<?> criteriaQuery, 				CriteriaBuilder criteriaBuilder) {

      if(searchForm==null) {
        return null;
      }

      List<Predicate> predicateList = new ArrayList<>();

      // 根據problemId精確查詢
      Predicate problemIdPredicate = null;
      if(searchForm.getProblemId()!=null) {
        problemIdPredicate = criteriaBuilder.equal(root.get("problemId").as(Integer.class), searchForm.getProblemId());
        predicateList.add(problemIdPredicate);
      }

      // 根據project精確查詢
      Predicate projectPredicate = null;
      if(searchForm.getProject()!=null && searchForm.getProject().getProjectId()!=null) {
        projectPredicate = criteriaBuilder.equal(root.get("project").as(MstProject.class), searchForm.getProject());
        predicateList.add(projectPredicate);
      }

      // 根據title模糊查詢
      Predicate titlePredicate = null;
      if(!StringUtils.isEmpty(searchForm.getTitle())) {
        titlePredicate = criteriaBuilder.like(root.get("title").as(String.class), "%"+searchForm.getTitle()+"%");
        predicateList.add(titlePredicate);
      }

      // 根據createTime範圍查詢
      Predicate createTimePredicate = null;
      if(searchForm.getCreateTimeStart()!=null && searchForm.getCreateTimeEnd()!=null) {
        createTimePredicate = criteriaBuilder.between(root.get("createTime").as(Date.class), searchForm.getCreateTimeStart(), searchForm.getCreateTimeEnd());
      } else if(searchForm.getCreateTimeStart()!=null) {
        createTimePredicate = criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(Date.class), searchForm.getCreateTimeStart());
      } else if(searchForm.getCreateTimeEnd()!=null) {
        createTimePredicate = criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(Date.class), searchForm.getCreateTimeEnd());
      }
      if(createTimePredicate!=null) {
        predicateList.add(createTimePredicate);
      }

      if(!CollectionUtils.isEmpty(predicateList)) {

        Predicate[] p = new Predicate[predicateList.size()];
        return criteriaBuilder.and(predicateList.toArray(p));
      }

      return null;
    }
  }, pageable);
}

上面的TranProblemRepository要繼承JpaSpecificationExecutor接口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章