QueryDSL简介

  QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查询。
  Querydsl可以通过一组通用的查询API为用户构建出适合不同类型ORM框架或者是SQL的查询语句,也就是说QueryDSL是基于各种ORM框架以及SQL之上的一个通用的查询框架。
借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建查询。目前QueryDSL支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。
官网地址:http://www.querydsl.com/static/querydsl/4.1.3/reference/html_single/

  Querydsl 是一个类型安全的 Java 查询框架,支持 JPA, JDO, JDBC, Lucene, Hibernate Search 等标准。类型安全( Type safety )和一致性( Consistency )是它设计的两大准则。在 Spring Boot 中可以很好的弥补 JPA 的不灵活,实现更强大的逻辑。

1.配置到项目

第一步:Maven引入依赖:
  首先对于queryDSL有两个版本,com.mysema.querydsl和com.querydsl,前者是3.X系列后者是4.X系列,这里使用的是后者.

 <dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency> <dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>

第二步:加入插件,用于生成查询实例,因为是类型安全的,所以还需要加上 Maven APT plugin ,使用 APT 自动生成一些类:

 <project>
<build>
<plugins>
...
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
</project>

  执行mvn compile之后,可以找到该target/generated-sources/java,然后IDEA标示为源代码目录即可

3.基本概念

  每一个 Model (使用  @javax.persistence.Entity  注解的), Querydsl 都会在同一个包下生成一个以 Q 开头(默认,可配置)的类,来实现便利的查询操作。
 Spring 提供了一个便捷的方式使用 Querydsl ,只需要在 Repository 中继承  QueryDslPredicateExecutor  即可:

@Repository public interface NoticeRespository extends JpaRepository<Notice,Long>, QueryDslPredicateExecutor<Notice> { }

然后就可以使用 UserRepository 无缝和 Querydsl 连接, QueryDslPredicateExecutor 接口提供了如下方法:

 public interface QueryDslPredicateExecutor<T> {  

     T findOne(Predicate predicate);  

     Iterable<T> findAll(Predicate predicate);  

     Iterable<T> findAll(Predicate predicate, Sort sort);  

     Iterable<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);  

     Iterable<T> findAll(OrderSpecifier<?>... orders);  

     Page<T> findAll(Predicate predicate, Pageable pageable);  

     long count(Predicate predicate);  

     boolean exists(Predicate predicate);
}

4.Spring 参数支持解析 com.querydsl.core.types.Predicate

  根据用户请求的参数自动生成 Predicate,这样搜索方法不用自己写啦,比如

 @GetMapping("posts")
public Object posts(@QuerydslPredicate(root = Post.class) Predicate predicate) {
return postRepository.findAll(predicate);
}
// 或者顺便加上分页
@GetMapping("posts")
public Object posts(@QuerydslPredicate(root = Post.class) Predicate predicate, Pageable pageable) {
return postRepository.findAll(predicate, pageable);
}

  

然后请求:

/posts?title=title01 // 返回文章 title 为 title01 的文章
/posts?id=2 // 返回文章 id 为 2 的文章
/posts?category.name=Python // 返回分类为 Python 的文章(你没看错,可以嵌套,访问关系表中父类属性)
/posts?user.id=2&category.name=Java // 返回用户 ID 为 2 且分类为 Java 的文章

   Pageable  是Spring Data库中定义的一个接口,该接口是所有分页相关信息的一个抽象,通过该接口,我们可以得到和分页相关所有信息(例如 pageNumber 、 pageSize 等)。
  Pageable定义了很多方法,但其核心的信息只有两个:一是分页的信息( page 、 size ),二是排序的信息。
  在springmvc的请求中只需要在方法的参数中直接定义一个 pageable 类型的参数,当Spring发现这个参数时,Spring会自动的根据request的参数来组装该pageable对象,Spring支持的request参数如下:
 page ,第几页,从0开始,默认为第0页
 size ,每一页的大小,默认为20
 sort ,排序相关的信息,以property,property(,ASC|DESC)的方式组织,例如sort=firstname&sort=lastname,desc表示在按firstname正序排列基础上按lastname倒序排列。

  这样,我们就可以通过url的参数来进行多样化、个性化的查询。
Spring data提供了 @PageableDefault 帮助我们个性化的设置pageable的默认配置。例如 @PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.DESC) 表示默认情况下我们按照id倒序排列,每一页的大小为15。

 @ResponseBody
@RequestMapping(value = "list", method=RequestMethod.GET)
public Page<blog> listByPageable(@PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.DESC)
Pageable pageable) {
return blogRepository.findAll(pageable);
}

4.注意,这样不会产生 SQL 注入问题的,因为不存在的属性写了是不起效果的, Spring 已经进行了判断。

   再补充一点,你还可以修改默认行为,继承 QueryDslPredicateExecutor 接口:

 @Repository
public interface NoticeRespository extends JpaRepository<Notice,Long>, QueryDslPredicateExecutor<Notice>,QuerydslBinderCustomizer<QNotice> { default void customize(QuerydslBindings bindings,QNotice notice){
bindings.bind(notice.content).first((path,value) ->path.contains(value).or(notice.title.contains(value)));
bindings.bind(notice.firsttime).first((path,value) ->notice.pushdate.after(value));
bindings.bind(notice.secondtime).first((path,value) ->notice.pushdate.before(value));
} }

  这样你再访问  /list?content=keywords  时,返回的是文章标题包含 keywords 或者内容包含keywords,而不是仅仅等于的所有文章啦!

  而且访问 /list?firsttime=2018.1.10&secontime=2018.1.11 时,返回的是pushdate在firsttime和secondtime之间的文章,只输入firsttime是之后的所有,只输入secondtime则是之前的所有文章。这样大大简化了操作!

5.实例

 package com.xunao.rubber.web.admin.notice;

 import com.xunao.rubber.domain.*;
import com.xunao.rubber.repository.NoticeRespository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.data.domain.Pageable;
import com.querydsl.core.types.Predicate; /**
* @author jinzhe
* @date 2018/1/10
*/
@Controller
@RequestMapping("/admin/notice")
public class AdminNoticeRecordController { @Autowired
private NoticeRespository noticeRespository; @GetMapping("/list")
public String notice(Model model,Notice notice,
@PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
@QuerydslPredicate(root = Notice.class) Predicate predicate) {
Page<Notice> notices = noticeRespository.findAll(predicate, pageable);
model.addAttribute("notices", notices);
return "admin/notice/list";
}
}

   predicate 除了之前在Respository里写的默认的条件外,还可以自己添加新的条件,例如:

predicate = QNotice.notice.pushdate.between(firsttime, secondtime).and(predicate); 
predicate = QNotice.notice.content.contains(keywords).and(predicate);

springboot带分页的条件查询的更多相关文章

  1. jqGrid jqGrid分页参数+条件查询

    HTML <div class="row"> <div class="col-sm-20"> <form id="for ...

  2. 分页离线条件查询 页面响应500 后端未报异常 list集合有数据

    如果 使用同一个Hibernate的DetachedCriteria离线条件查询对象同时查询“过滤后条数” 和 “过滤后的数据集合”,那么查询记录数时需要设置聚合函数条件并且 使用聚合函数  代码要在 ...

  3. 【JPA】Spring Data JPA 实现分页和条件查询

    文章目录 1.在`Repository`层继承两个接口 2.在Service层进行查询操作 3.Page的方法 1.在Repository层继承两个接口 JpaRepository<Admin, ...

  4. ajxa分页+多条件查询

    操作日志数据库表: 主页面: <script src="../fzl/jquery-1.11.2.min.js"></script> <script ...

  5. MongoTemplate 分组分页复合条件查询

    一.前言 最近项目使用MongoDB作为数据主要存取的地方 又是第一次接触MongoDB,也是踩了不少坑... 维护数据无非就是增删改查,而里面最复杂的就是查询了 所以来总结一下有关MongoDB的查 ...

  6. django项目中的ajax分页和条件查询。

    1,路由 #主页面路由 re_path('article/article_list/', article.article_list,name='article/article_list/'), #分页 ...

  7. think php 多条件检索+自带分页+多条件搜索标红分页

    //视图<form action="/homework/homework/index" method="get"> <input type=& ...

  8. spring JPA分页排序条件查询

    @RequestMapping("/listByPage") public Page<Production> listByPage(int page, int size ...

  9. 动态多条件查询分页以及排序(一)--MVC与Entity Framework版url分页版

    一.前言 多条件查询分页以及排序  每个系统里都会有这个的代码 做好这块 可以大大提高开发效率  所以博主分享下自己的6个版本的 多条件查询分页以及排序 二.目前状况 不论是ado.net 还是EF ...

随机推荐

  1. Microsoft Sync Framework 2.1 可再发行程序包 Microsoft Sync Framework 1.0 SP1 - 中文(简体)

    Sync Framework 2.1 引入了新功能,这些功能支持您计算机上的 SQL Server 或 SQL Server Compact 数据库与 SQL Azure 数据库进行同步.此发行版还引 ...

  2. Loadrunner 工作原理图

    1.LoadRunner的总体架构图,从图中可以看出组件VUGen, Controller和Analysis之间的关系. 2.LoadRunner的工作原理,从图中可以看出如何利用LoadRunner ...

  3. Angular 学习笔记——shop

    <!DOCTYPE html> <html lang="en" ng-app> <head> <meta charset="UT ...

  4. dev_queue_xmit()函数返回值问题

    函数  dev_queue_xmit()用于直接使用sk_buf发包,此函数有返回值,但是并不能通过 此函数返回值为0来说明包已经发送出去且可以立刻释放sk_buff内存.因为网卡发包是一个异步的过程 ...

  5. vuex简单示例

    一.vuex是什么,解决了什么问题? 官方解释是:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生 ...

  6. JavaWeb Cookie详解

    代码地址如下:http://www.demodashi.com/demo/12713.html Cookie的由来 首先我们需要介绍一下,在Web开发过程中为什么会引入Cookie.我们知道Http协 ...

  7. jenkins构建java项目找不到命令mvn,java的解决方法

    jenkins构建java项目时出现的报错情况: $ mvn clean install FATAL: command execution failed java.io.IOException: er ...

  8. windows小游戏之扫雷技巧

    通过单击即可挖开方块.如果挖开的是地雷,则您输掉游戏. 如果方块上出现数字,则表示在其周围的八个方块中共有多少颗地雷.

  9. JavaSE入门学习21:Java面向对象之接口(interface)(二)

    一接口实现的多态 在上一篇博文:JavaSE入门学习20:Java面向对象之接口(interface)(一)中提到了接口的实现存在多态性,那么 这一篇主要就要分析接口实现的多态. 实例一 Test.j ...

  10. tcpdump command

    工作中一直在用tcpdump,感觉非常方便,今天心血来潮百度了一下tcpdump的用法,才发现原来还有这么多强大的功能自己都不知道,那叫一个汗啊. 以此文作为备份,记录一些新知道的用法,各位网友谁有新 ...