2019独角兽企业重金招聘Python工程师标准>>>

场景如下:很简单的CMS常用查询,栏目下有多个子栏目,子栏目有包含内容。

public class Channel{
....
private String parentIds;//所有的父节点,简化查询策略 例如 0,1,11,
private List<Channel> channels = Lists.newArrayList(); //所有的儿子栏目
...
}  public class Content{  private Channel channel; //属于哪个栏目
}  

所以比如有如下结构时:栏目A下有两个子栏目B,C;这三个栏目下都有各自的内容, 那么当查询A下的内容时,肯定也是要包含B,C栏目下的内容。

比如说A栏目的id是 10 ,再加上别的查询条件的话, 也就是说 sql 语句肯定是类似:

select * from Content as s where (s.channel.id = 10 or s.channel.parentIds like '%,10,%') and s.yyy = 'xxxxx' and s.xxx = 'yyyy';  

想来想去发现实在没有简单的办法做or查询之后跟动态的and查询参数,好像只能自己构造,所以在此记录一下,避免忘记。

此处动态的and 查询条件构造是使用了springside的方法。并且我不知道这样的构造方法是不是spring-data-jpa的标准做法,如果不是,请指正

/** * 查询某个栏目下的所有文章,并且分页。 *  * 如该栏目下有子栏目,则需要一起显示 *  * @param channelId 栏目id * @param searchParams * @param pageNumber * @param pageSize * @return */  public Page<Content> getContentListPaged(final Integer channelId,final Collection<SearchFilter> filters,int pageNumber, int pageSize){  return contentDao.findAll(new Specification<Content>(){  @Override  public Predicate toPredicate(Root<Content> root,  CriteriaQuery<?> query, CriteriaBuilder builder) {  //path转化  List<Predicate> orPredicates = Lists.newArrayList();  Path<String> idPath = root.get("channel").get("id");  Path<String> parentIdsPath = root.get("channel").get("parentIds");  Predicate p1 = builder.equal(root.get("channel").get("id"), channelId);  orPredicates.add(builder.or(p1));  Predicate p2 = builder.like((Path)root.get("channel").get("parentIds"), "%," + channelId + ",%");  orPredicates.add(builder.or(p2));  //以下是springside3提供的方法  Predicate o = DynamicSpecifications.bySearchFilter(filters, Content.class).toPredicate(root, query, builder);  Predicate p = builder.or(orPredicates.toArray(new Predicate[orPredicates.size()]));  query.where(p,o);  return null;  }  }, new PageRequest(pageNumber - 1, pageSize));  }  

实际查询的输出sql如下,where之前省略:

where  content0_.channel_id=channel1_.id   and (  content0_.channel_id=21   or channel1_.parentIds like ?  )   and (  content0_.title like ?  ) limit ?  

另一个使用案例:

前端返回的查询结构:{"字段名1":"字段值1","字段名2":"字段值2"}

        Sort sort = new Sort(Sort.Direction.DESC, "id");Pageable pageable = new PageRequest(page<0?0:page, size<0?1:size, sort);if(filters != null){JSONObject params = JSON.parseObject(filters);Set<String> keys = params.keySet();if(keys.size() > 0){Specification<LogViewModel> spec = new Specification<LogViewModel>() {public Predicate toPredicate(Root<LogViewModel> root, CriteriaQuery<?> query, CriteriaBuilder cb) {List<Predicate> andPredicates = Lists.newArrayList();for(String key : keys){if(StringUtils.isNotBlank(params.getString(key)))andPredicates.add(cb.like(root.get(key),"%"+params.getString(key)+"%"));}Predicate p = cb.and(andPredicates.toArray(new Predicate[andPredicates.size()]));query.where(p);return null;}};return logViewManager.findAll(spec,pageable);}}

转载于:https://my.oschina.net/u/2391658/blog/1514047

spring-data-jpa 复杂查询的写法(包含or的查询)相关推荐

  1. spring data jpa封装specification实现简单风格的动态查询

    github:https://github.com/peterowang/spring-data-jpa-demo 单一实体的动态查询: @Servicepublic class AdvancedUs ...

  2. Spring Data JPA 从入门到精通~@NamedQueries预定义查询

    这种是预定义查询的一种形式 (1)在 @Entity 下增加 @NamedQuery 定义. public @interface NamedQuery {//query的名称,规则:实体.方法名:St ...

  3. Spring data JPA -针对一对多关系中,分页查询一的一方部分,但查询条件中有多的一方参数

    jpa框架让大家快速实现增删查改,真是太方便了.但是针对以下这个场景大家需要注意一下,我们项目中真实用到的,记录下来分享给大家. Account 和AccountDetail 是一对多关系,正常针对A ...

  4. 【Spring Data JPA自学笔记三】Spring Data JPA的基础和高级查询方法

    文章目录 调用接口的基础方法查询 Repository CrudRepository PagingAndSortingRepository JPARepository JpaSpecification ...

  5. Spring Data JPA 从入门到精通~查询结果的处理

    参数选择(Sort/Pageable)分页和排序 特定类型的参数,Pageable 并动态 Sort 地将分页和排序应用于查询 案例:在查询方法中使用 Pageable.Slice 和 Sort. P ...

  6. Spring Data JPA 查询方法的命名语法与参数

    3 Spring Data JPA 查询方法的命名语法与参数 在⼯作中,你是否经常为⽅法名的语义.命名规范⽽发愁?是否要为不同的查询条件写各种的 SQL 语句?是否为同⼀个实体的查询,写⼀个超级通⽤的 ...

  7. Spring Data JPA 实例查询

    转自:https://www.cnblogs.com/rulian/p/6533109.html 一.相关接口方法 在继承JpaRepository接口后,自动拥有了按"实例"进行 ...

  8. ORM框架之Spring Data JPA(三)高级查询---复杂查询

    一.spring data jpa高级查询 1.1Specifications动态查询 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data ...

  9. Spring Data JPA 必须掌握的 20+ 个查询关键字

    微信公众号:一个优秀的废人 如有问题或建议,请后台留言,我会尽力解决你的问题. 前言 又是小师弟的投稿,确是一个喜欢技术的朋友.以下为原文: 今天闲的无聊看 Spring Data JPA 官方文档的 ...

  10. Spring Data JPA 多条件判空查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询. 使用@Query注解,这种方式可以直接在Repository里面写sql,但是这种方式的问题 ...

最新文章

  1. 调用链系列四:调用链上下文传递
  2. latex 文章前头引用包
  3. Oracle-逻辑体系结构
  4. [react] 怎样在react中创建一个事件?
  5. 简易的遍历文件加密解密
  6. 【正则表达式】IPv4地址的正则匹配
  7. access insert语句怎么写_擦亮自己的眼睛去看SQLServer之简单Insert
  8. win下mysql数据库双机配置_[数据库]windows下使用mysql双机热备功能
  9. 活久见: maven pom 竟然都会崩溃!
  10. 微处理器系统结构与嵌入式系统设计(二)
  11. debian 安装teamviewer
  12. 全国青少年软件编程等级考试标准Python(1-6级)
  13. Batch Normalization :深度网络中的BN层
  14. 机器学习:深度信念网络(DBN)原理和实现
  15. linux网络凭据,适用于Linux和Windows的服务器凭据管理
  16. [BJDCTF2020]ZJCTF,不过如此
  17. 关于项目管理的通俗讲解
  18. 接到阿里HR面试通过电话的那天我哭了,奋战6个月终进阿里定级P6+
  19. 谭浩强C程序设计快速复习笔记
  20. 程控仪器标准命令SCPI

热门文章

  1. Rust 编程语言曝高危漏洞,可导致文件和目录遭删除
  2. 白宫发布太空系统网络安全防护指令
  3. Intel 警告注意 CSME 引擎中的严重漏洞,发布产品停产通知
  4. 中英金融科技论坛:监管科技增长较快 区块链等新技术挑战监管能力
  5. 比特币里面有哪些天才的设计?
  6. MySQL备份,恢复方案,mysqlbinlog,mysqldump,主从,主主复制
  7. 夜上海音乐播放器 v 1.0
  8. Linux 之 hugepage 大页内存理论
  9. 现实世界中正在用Java解决的难题
  10. 前端开发学习之——dom ready和window onload的区别