二、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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
2025年4月中国数据库流行度排行榜:OB高分复登顶,崖山稳驭撼十强
墨天轮编辑部
2505次阅读
2025-04-09 15:33:27
数据库国产化替代深化:DBA的机遇与挑战
代晓磊
1164次阅读
2025-04-27 16:53:22
2025年3月国产数据库中标情况一览:TDSQL大单622万、GaussDB大单581万……
通讯员
846次阅读
2025-04-10 15:35:48
2025年4月国产数据库中标情况一览:4个千万元级项目,GaussDB与OceanBase大放异彩!
通讯员
659次阅读
2025-04-30 15:24:06
数据库,没有关税却有壁垒
多明戈教你玩狼人杀
577次阅读
2025-04-11 09:38:42
天津市政府数据库框采结果公布,7家数据库产品入选!
通讯员
561次阅读
2025-04-10 12:32:35
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
539次阅读
2025-04-14 09:40:20
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
475次阅读
2025-04-17 17:02:24
一页概览:Oracle GoldenGate
甲骨文云技术
457次阅读
2025-04-30 12:17:56
GoldenDB数据库v7.2焕新发布,助力全行业数据库平滑替代
GoldenDB分布式数据库
451次阅读
2025-04-30 12:17:50