文档章节

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

孟飞阳
 孟飞阳
发布于 2017/08/18 15:36
字数 601
阅读 762
收藏 0
jpa


场景如下:很简单的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);
            }
        }

 

© 著作权归作者所有

孟飞阳
粉丝 217
博文 1056
码字总数 566359
作品 5
朝阳
个人站长
私信 提问
Spring Boot [组件学习-Spring Data JPA]

导读: 在上篇文章中对Spring MVC常用的一些注解做了简要的说明,在这篇文章中主要对Spring Data JPA 做一个简要的说明,并附有一个简单的例子,可以体会到Spring Data JPA 的强大之处。 Sp...

yangrd
2018/08/27
0
0
(入门帖)使用 Spring Data JPA 简化 JPA 开发

本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示例;接着重构该示例,并引入 Spring 框架,这两部分...

阿莱倪士
2014/01/09
668
0
Spring Data JPA 使用

Java 持久层框架访问数据库的方式大致分为两种。一种以 SQL 中心,封装一定程度的 JDBC 操作,比如 MyBatis。另一种是以 Java Entity 为中心,将实体的关系对应到数据库表之间的关系,如 OR...

TurboSanil
06/13
226
0
使用 Spring Data JPA 简化 JPA 开发

从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示例;接着重构该示例,并...

IBMdW
2012/03/02
4.4K
8
一步步学习 Spring Data 系列之JPA(一)

大概有半年多没有写博客了,主要是最近忙于工作,也没来得及与大家分享技术。当然现在的技术大多都有人写其博客分享了,也找不到合适写的,所以也就懒得写了。最近在SpringSource上看到了一好...

张廷
2012/07/23
13.8K
3

没有更多内容

加载失败,请刷新页面

加载更多

DevOps是如何实现效率的提升?

随着企业业务对软件系统日益依赖,IT管理与研发模式也随之对“敏态”模式产生了需求,也就是今天时常提起的DevOps。提升效率,是DevOps实践的核心内容之一。就让我们来一起从软件生命周期的业...

嘉为科技
20分钟前
2
0
总结:linux目录之proc

我们系统大部分的基础数据采集,其实就是读取proc目录下的文件,并解析获取数据的过程。 1、如cpu利用率:直接cat /proc/cpuinfo命令,然后获取输出内容,并解析里面的数据,如cpu核数等; ...

浮躁的码农
21分钟前
2
0
比原Bapp红包应用

喜迎国庆期间,比原链在自己的移动端钱包Bycoin(下载地址)和google插件钱byone中推出了红包应用,在国庆期间深受大家好评。 那我们今天就来大概介绍一下比原红包,以及基于比原链开发dapp应用...

比原链Bytom
23分钟前
2
0
Linux中没有rc.local文件的解决方法

Linux中没有rc.local文件的解决方法是什么呢?这应该是很多工程师比较头疼的问题,下面就给大家例举几个解决办法。 比较新的Linux发行版已经没有rc.local文件了。因为已经将其服务化了。 解决...

xiangyunyan
23分钟前
2
0
数据中台在阿里巴巴集团内部的实践情况

作者:品鉴 数据中台门在阿里巴巴集团干什么的,由哪个部门掌管?数据中台在阿里巴巴的主要作用是什么呢?外面吹嘘这么神秘的数据中台在阿里实践的如何呢?今天小编正好要采访数据技术及产品...

阿里云官方博客
23分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部