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