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接口