二、JPA多条件查询
我们依然使用昨天的Repository 但是仅仅继承JpaRepository是不够的,若要完成复杂查询则需要继承JpaSpecification<Person> “<>”里面存放的是该接口需要操作的实体类对象,我们仍以昨天的Person类对象为例。
@Repository
public interface PersonRepository extends JpaRepository<Person,Long>, JpaSpecificationExecutor<Person> {
}
复制
实现的步骤首先是创建一个specification 对象,然后实现里面的toPredicate()方法,然后可以使用if语句动态的构建查询参数,前端传入相应的参数,就拼接对应的查询语句,该字段为null则不拼接对应的查询语句,非常的方便灵活。拼接好相应的查询语句后,再利用and连接构建一个predicate 对象。最后传入specification、pageable等参数,使用repository已经帮我们实现的findAll(specification, pageable)方法实现分页(排序)的多条件查询。该方法将返回一个page对象,里面包含了分页数据以及分页信息。
构建查询语句时,其中的api设计和SQL本来的原意很相近,容易理解。具体相关的api都以注释的形式放在代码中。这些非常直观的api可以帮助我们拼接成丰富多彩的查询语句,避免我们手动去写原生的SQL语句。
/**
* todo spring data jpa 使用specification 进行查询 3-11
* 十分实用和好用
*
* @param query
* @return
*/
public Page<Person> queryPersonsByLamdaConditions(PersonQuery query) {
// List<Sort.Order> orders = new ArrayList<>();
// Sort.Order order1= new Sort.Order(Sort.Direction.ASC,"createTime");
// Sort.Order order2= new Sort.Order(Sort.Direction.ASC,"personType");
// orders.add(order2);
// orders.add(order1);
// new Sort(orders)
// 多个字段进行排序
Sort sort = new Sort(Sort.Direction.DESC, "personType").
and(new Sort(Sort.Direction.ASC, "createTime"));
Pageable pageable = PageRequest.of(query.getPage() - 1, query.getPageSize(), sort);
// 先创建一个说明书, 借助这个说明书进行查询
Specification<Person> specification = new Specification<Person>() {
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
// 然后再创建一个查询预测条件的数组
List<Predicate> list = new ArrayList<>();
// 模糊查询 like
if (StringUtils.isNotBlank(query.getUserName())) {
list.add(criteriaBuilder.like(root.get("userName"), query.getUserName()));
}
// 等于 equal
if (query.getAge() != null) {
list.add(criteriaBuilder.equal(root.get("age"), query.getAge()));
}
// where in list集合
if (CollectionUtils.isNotEmpty(query.getUnitIds())) {
list.add(criteriaBuilder.in(root.get("unitId")).value(query.getUnitIds()));
}
if (Objects.nonNull(query.getCreateTime())) {
// 大于等于
// list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), query.getCreateTime()));
// 大于
// list.add(criteriaBuilder.greaterThan(root.get("createTime"), query.getCreateTime()));
// 小于等于
// list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), query.getCreateTime()));
// 小于
list.add(criteriaBuilder.lessThan(root.get("createTime"), query.getCreateTime()));
}
// 介于二者之间的
if (Objects.nonNull(query.getStartTime()) && Objects.nonNull(query.getEndTime())) {
list.add(criteriaBuilder.between(root.get("createTime"), query.getStartTime(), query.getEndTime()));
}
Predicate[] predicates = new Predicate[list.size()];
// 将其转换成predicate数组
return criteriaBuilder.and(list.toArray(predicates));
}
};
Page<Person> page = personRepository.findAll(specification, pageable);
List<Person> personEntities = page.getContent();
// 此处可以将 personEntities 可以再转换为vo
// List<PersonVo> personVoList = MapperUtil.mapperObjectList(PersonVo.class, personEntities);
// 再新构建一个page页面
return new PageImpl<>(personEntities, pageable, page.getTotalElements());
}
复制
三、小结
面对一些多条件复杂查询,JPA内置方法以及通过方法名构建的简单方法已经不能满足我们的需求,这时候需要在repository中继承JpaSpecificationExecutor接口,然后创建一个specification对象和pageable对象,调用findAll(specification,pageable)方法完成多条件的查询任务。
文章转载自DevHome,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【专家观点】罗敏:从理论到真实SQL,感受DeepSeek如何做性能优化
墨天轮编辑部
1269次阅读
2025-03-06 16:45:38
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1268次阅读
2025-03-13 11:40:53
2025年2月国产数据库大事记
墨天轮编辑部
992次阅读
2025-03-05 12:27:34
2025年2月国产数据库中标情况一览:GoldenDB 3500+万!达梦近千万!
通讯员
875次阅读
2025-03-06 11:40:20
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
452次阅读
2025-03-13 14:38:19
AI的优化能力,取决于你问问题的能力!
潇湘秦
419次阅读
2025-03-11 11:18:22
优炫数据库成功应用于国家电投集团青海海南州新能源电厂!
优炫软件
339次阅读
2025-03-21 10:34:08
达梦数据与法本信息签署战略合作协议
达梦数据
291次阅读
2025-03-06 09:26:57
国产化+性能王炸!这套国产方案让 3.5T 数据 5 小时“无感搬家”
YMatrix
275次阅读
2025-03-13 09:51:26
磐维数据库对外门户全新升级!
磐维数据库
240次阅读
2025-03-04 15:32:59