当前位置: 首页 > 编程日记 > 正文

JPA 复杂查询 - Querydsl

 添加依赖

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


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

运行 mvn compile, 将生成Query实体。

单表查询

package com.chhliu.springboot.jpa.repository;import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;import com.chhliu.springboot.jpa.entity.QUser;
import com.chhliu.springboot.jpa.entity.User;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;/*** 描述:QueryDSL JPA* @author chhliu*/
@Component
@Transactional
public class UserRepositoryManagerDsl {@Autowiredprivate UserRepositoryDls repository;@Autowired@PersistenceContextprivate EntityManager entityManager;private JPAQueryFactory queryFactory;@PostConstructpublic void init() {queryFactory = new JPAQueryFactory(entityManager);}public User findUserByUserName(final String userName){/*** 该例是使用spring data QueryDSL实现*/QUser quser = QUser.user;Predicate predicate = quser.name.eq(userName);return repository.findOne(predicate);}/*** attention:* Details:查询user表中的所有记录*/public List<User> findAll(){QUser quser = QUser.user;return queryFactory.selectFrom(quser).fetch();}/*** Details:单条件查询*/public User findOneByUserName(final String userName){QUser quser = QUser.user;return queryFactory.selectFrom(quser).where(quser.name.eq(userName)).fetchOne();}/*** Details:单表多条件查询*/public User findOneByUserNameAndAddress(final String userName, final String address){QUser quser = QUser.user;return queryFactory.select(quser).from(quser) // 上面两句代码等价与selectFrom.where(quser.name.eq(userName).and(quser.address.eq(address)))// 这句代码等同于where(quser.name.eq(userName), quser.address.eq(address))
            .fetchOne();}/*** Details:使用join查询*/public List<User> findUsersByJoin(){QUser quser = QUser.user;QUser userName = new QUser("name");return queryFactory.selectFrom(quser).innerJoin(quser).on(quser.id.intValue().eq(userName.id.intValue())).fetch();}/*** Details:将查询结果排序*/public List<User> findUserAndOrder(){QUser quser = QUser.user;return queryFactory.selectFrom(quser).orderBy(quser.id.desc()).fetch();}/*** Details:Group By使用*/public List<String> findUserByGroup(){QUser quser = QUser.user;return queryFactory.select(quser.name).from(quser).groupBy(quser.name).fetch();}/*** Details:删除用户*/public long deleteUser(String userName){QUser quser = QUser.user;return queryFactory.delete(quser).where(quser.name.eq(userName)).execute();}/*** Details:更新记录*/public long updateUser(final User u, final String userName){QUser quser = QUser.user;return queryFactory.update(quser).where(quser.name.eq(userName)).set(quser.name, u.getName()).set(quser.age, u.getAge()).set(quser.address, u.getAddress()).execute();}/*** Details:使用原生Query*/public User findOneUserByOriginalSql(final String userName){QUser quser = QUser.user;Query query = queryFactory.selectFrom(quser).where(quser.name.eq(userName)).createQuery();return (User) query.getSingleResult();}/*** Details:分页查询单表*/public Page<User> findAllAndPager(final int offset, final int pageSize){Predicate predicate = QUser.user.id.lt(10);Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "id"));PageRequest pr = new PageRequest(offset, pageSize, sort);return repository.findAll(predicate, pr);}
}

多表操作示例(一对一)

package com.chhliu.springboot.jpa.repository;import java.util.ArrayList;
import java.util.List;import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import com.chhliu.springboot.jpa.dto.PersonIDCardDto;
import com.chhliu.springboot.jpa.entity.QIDCard;
import com.chhliu.springboot.jpa.entity.QPerson;
import com.querydsl.core.QueryResults;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;@Component
public class PersonAndIDCardManager {@Autowired@PersistenceContextprivate EntityManager entityManager;private JPAQueryFactory queryFactory;@PostConstructpublic void init() {queryFactory = new JPAQueryFactory(entityManager);}/*** Details:多表动态查询*/public List<Tuple> findAllPersonAndIdCard(){Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());JPAQuery<Tuple> jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name).from(QIDCard.iDCard, QPerson.person).where(predicate);return jpaQuery.fetch();}/*** Details:将查询结果以DTO的方式输出*/public List<PersonIDCardDto> findByDTO(){Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());JPAQuery<Tuple> jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name).from(QIDCard.iDCard, QPerson.person).where(predicate);List<Tuple> tuples = jpaQuery.fetch();List<PersonIDCardDto> dtos = new ArrayList<PersonIDCardDto>();if(null != tuples && !tuples.isEmpty()){for(Tuple tuple:tuples){String address = tuple.get(QPerson.person.address);String name = tuple.get(QPerson.person.name);String idCard = tuple.get(QIDCard.iDCard.idNo);PersonIDCardDto dto = new PersonIDCardDto();dto.setAddress(address);dto.setIdNo(idCard);dto.setName(name);dtos.add(dto);}}return dtos;}/*** Details:多表动态查询,并分页*/public QueryResults<Tuple> findByDtoAndPager(int offset, int pageSize){Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());return queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name).from(QIDCard.iDCard, QPerson.person).where(predicate).offset(offset).limit(pageSize).fetchResults();}
}

上面将查询结果以DTO的方式输出的示例中,在查询结束后,将查询结果手动的转换成了DTO对象,这种方式其实不太优雅,QueryDSL给我们提供了更好的方式,见下面的示例:

/*** Details:方式一:使用Bean投影*/public List<PersonIDCardDto> findByDTOUseBean(){Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());return queryFactory.select(Projections.bean(PersonIDCardDto.class, QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name)).from(QIDCard.iDCard, QPerson.person).where(predicate).fetch();}/*** Details:方式二:使用fields来代替setter*/public List<PersonIDCardDto> findByDTOUseFields(){Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());return queryFactory.select(Projections.fields(PersonIDCardDto.class, QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name)).from(QIDCard.iDCard, QPerson.person).where(predicate).fetch();}/*** Details:方式三:使用构造方法,注意构造方法中属性的顺序必须和构造器中的顺序一致*/public List<PersonIDCardDto> findByDTOUseConstructor(){Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());return queryFactory.select(Projections.constructor(PersonIDCardDto.class, QPerson.person.name, QPerson.person.address, QIDCard.iDCard.idNo)).from(QIDCard.iDCard, QPerson.person).where(predicate).fetch();}

上面只是提供了几种思路,当然,还可以使用@QueryProjection来实现,非常灵活。
一对多示例:

package com.chhliu.springboot.jpa.repository;import java.util.List;import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import com.chhliu.springboot.jpa.entity.QOrder;
import com.chhliu.springboot.jpa.entity.QOrderItem;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;@Component
public class OrderAndOrderItemManager {@Autowired@PersistenceContextprivate EntityManager entityManager;private JPAQueryFactory queryFactory;@PostConstructpublic void init() {queryFactory = new JPAQueryFactory(entityManager);}/*** Details:一对多,条件查询*/public List<Tuple> findOrderAndOrderItemByOrderName(String orderName){//添加查询条件Predicate predicate = QOrder.order.orderName.eq(orderName);JPAQuery<Tuple> jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem).from(QOrder.order, QOrderItem.orderItem).where(QOrderItem.orderItem.order.id.intValue().eq(QOrder.order.id.intValue()), predicate);//拿到结果return jpaQuery.fetch();}/*** Details:多表连接查询*/public List<Tuple> findAllByOrderName(String orderName){//添加查询条件Predicate predicate = QOrder.order.orderName.eq(orderName);JPAQuery<Tuple> jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem).from(QOrder.order, QOrderItem.orderItem).rightJoin(QOrder.order).on(QOrderItem.orderItem.order.id.intValue().eq(QOrder.order.id.intValue()));jpaQuery.where(predicate);//拿到结果return jpaQuery.fetch();}
}

链接

Querydsl Reference Guide

使用QueryDSL

复杂查询的封装

spring boot-jpa整合QueryDSL来简化复杂操作

Spring Boot JPA - 使用 Querydsl 处理复杂的操作

转载于:https://www.cnblogs.com/tonyq/p/7881142.html

相关文章:

服务器端开发经验总结 Linux C语言

简介在进行服务器端开发的时候需要考虑一些算法和性能问题&#xff0c;经过了几年的开发&#xff0c;对这方面有了一些经验&#xff0c;现在写下来跟大家分享和讨论。我主要是在Linux下进行C语言的开发&#xff0c;所以后面的实现都是基于Linux操作系统并用C语言来讲解。其它平…

Backbone.js学习笔记 Hello World!

使用Backbone.js 和 MVC 架构创建一个典型的Hello world项目。虽然是“杀鸡用牛刀了”&#xff0c;毕竟是我第一次使用Backbone.js 依赖 jQuery 1.9.1Undersore.js 1.5.0Backbone.js开始 <!doctype html> <html> <head> <meta charset"utf-8"&g…

一文速览机器学习的类别(Python代码)

作者&#xff1a;泳鱼来源&#xff1a;算法进阶机器学习按照学习数据经验的不同&#xff0c;即训练数据的标签信息的差异&#xff0c;可以分为&#xff1a;*监督学习&#xff08;supervised learning&#xff09;*非监督学习&#xff08;unsupervised learning&#xff09;*半监…

Linux下分割与合并文件的方法

Linux下分割与合并文件的方法 切割合并文件在linux下用split和cat就可以完成。下面举些实例进行说明。1.文件切割文件切割模式分为两种&#xff1a; 文本文件 二进制模式。 1.1文本模式 文本模式只适用于文本文件&#xff0c;用这种模式切割后的每个文件都是可读的。文本模式又…

将网站程序放在tmpfs下

将网站程序放在tmpfs下然后用nginx直接做对外服务呢varnish或者squid都是利用内存和它的连接数来做到加速服务.但是如果是squid->nginx->fastcgi->mysql这样当中很多连接是开销在内部的连接之中而且如果客户端请求php.squid还需要将请求再转发至nginx,然后nginx再转发…

docker 连接容器

1.通过端口映射 sudo docker run -d -P training/webapp python app.py 容器有一个内部网络和IP地址&#xff08;在使用Docker部分我们使用docker inspect命令显示容器的IP地址&#xff09; -P 标记创建一个容器&#xff0c;将容器的内部端口随机映射到主机的高端口49000到4990…

新进展!英伟达用 AI 给纪录片配音,情绪语调拿捏得稳稳地

编译 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; AI 已经将合成语音从单调的机器人电话和传统 GPS 导航系统转变为智能手机和智能扬声器中动听的虚拟助手。 虽然日常和Siri、小爱或小度等对话时声音还是很机械&#xff0c;但最新的技术进展显示&#x…

揭开Annotation的面纱

Annotation是Java5、6只后的新特征&#xff08;中文称之为注解&#xff09;&#xff0c;并且越来越多的得到了应用&#xff0c;比如Spring、Hibernate3、Struts2、iBatis3、JPA、JUnit等等都得到了广泛应用&#xff0c;通过使用注解&#xff0c;代码的灵活性大大提高。这些都是…

使用Nginx的proxy_cache缓存功能取代Squid

[文章作者&#xff1a;张宴 本文版本&#xff1a;v1.2 最后修改&#xff1a;2009.01.12 转载请注明原文链接&#xff1a;http://blog.s135.com/nginx_cache/]  Nginx从0.7.48版本开始&#xff0c;支持了类似Squid的缓存功能。这个缓存是把URL及相关组合当作Key&#xff0c;用…

oracle grant 权限

grant connect,resource,dba to user;CONNECT角色&#xff1a; --是授予最终用户的典型权利&#xff0c;最基本的 CREATE SESSION --建立会话 RESOURCE角色&#xff1a; --是授予开发人员的 CREATE CLUSTER --建立聚簇 CREATE …

技术沙龙 | TeaTalk 带你深度探索 SDN 网络技术再创新

越来越多的企业、行业和政府机关顺应企业数字化转型、云服务和国家政策等趋势将业务迁移上云。随着移动云的快速发展&#xff0c;对网络提供差异化的服务能力也提出了很多新的考验。大规模数据中心、虚拟化 SDN 网络技术及超融合软硬一体可编程设备在云网络的应用已成为行业发展…

利用windows 2003实现服务器群集的搭建与架设(一) NLB群集的创建与架设

实验场景&#xff1a;西安凌云系统高科技有限公司利用IIS搭建了一个WEB站点&#xff0c;域名为nlb.angeldevil.com。由于业务的逐渐增加&#xff0c;网站速度也越来越慢&#xff0c;而且经常出现故障&#xff0c;为公司的利益带来了很多的不便&#xff1b;公司决定使用两台WEB站…

nginx 反向代理,动静态请求分离,proxy_cache缓存及缓存清除

一&#xff0c;nginx反向代理配置 #tomcat 显然就是用户访问www.wolfdream.com(需要设置本地localhost&#xff0c;将www.wolfdream.com指向nginx所在IP)的时候(或将www.wolfdream.com直接写在nginx所在的IP地址)&#xff0c;将请求转到到后台的tomcat服务器&#xff0c;即127.…

深度强化学习的前景:帮助机器掌控复杂性

作者&#xff1a;数据实战派 来源&#xff1a;数据实战派深度强化学习&#xff0c;即机器通过测试其行为后果来学习的方法&#xff0c;是人工智能最有前途和影响力的领域之一。它将深度神经网络与强化学习结合在一起&#xff0c;可以通过训练实现多个步骤的目标。它是自动驾驶汽…

成绩转换(15)

#include<stdio.h> int main() {int n;char ch;while(scanf("%d",&n)!EOF){if(n>100||n<0) continue;if(n>90) chA;else if(n>80) chB;else if(n>70) chC;else if(n>60) chD;else chE;printf("%c\n",ch);} }转载于:https://ww…

pangolin最新版 v2.5.2.975

Pangolin是一款帮助渗透测试人员进行Sql注入测试的安全工具。 所谓的SQL注入测试就是通过利用目标网站的某个页面缺少对用户传递参数控制或者控制的不够好的情况下出现的漏洞&#xff0c;从而达到获取、修改、删除数据&#xff0c;甚至控制数据库服务器、Web服务器的目的的测试…

nginx 的proxy_cache才是王道

nginx 的proxy_cache才是性价比最高的缓存,我目前的配置是LiteSpeednginx,可以参考apachenginx将动态内容交给LiteSpeed或apache来处理,然后利用proxy_cache反向代理全部缓存在硬盘,变成静态内容,大家都知道nginx跑静态内容是有多厉害了吧,所以这样就可以小内存跑大PV.但是这样…

Android 占位符 %1$s %1$d

1、整型&#xff0c;比如“我今年23岁了”&#xff0c;这个23是整型的。在string.xml中可以这样写&#xff0c;<string name"old">我今年%1$d岁了</string> 在程序中&#xff0c;使用 [java] view plaincopy String sAgeFormat getResources().getStrin…

谁说技术男不适合养猫!90后程序员2天做出猫咪情绪识别软件

整理 | 王晓曼出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;9月1日&#xff0c;一则关于#程序员2天做出猫咪情绪识别软件#的话题登上微博热搜&#xff0c;参与阅读的人数达到了8218.1万&#xff0c;讨论次数1.3万&#xff0c;引发网友们的热议。高手在民间&#…

符合RESTful的接口规范

把api放在专属域名下&#xff0c;要带版本号 api的url中应该只有名词&#xff0c;和数据库的表或文档资源相对应&#xff1b;对资源&#xff08;collection&#xff09;的具体操作类型则由http方法动词表示 &#xff08;安全性&#xff1a;不改变资源状态&#xff0c;类似只读&…

Nginx proxy_cache 使用示例

原文出处&#xff1a;http://blog.chenlb.com/2010/04/nginx-proxy-cache.html 动态网站使用缓存是很有必要的。前段时间使用了 nginx proxy_stroe 来保存静态页面&#xff0c;以达到缓存的目的。当然 proxy stroe 用来做缓存是不够好的方案。 缓存这一块当然还有 squid 之类的…

Lync 小技巧-49-Lync 自动备份-批量管理-用户(免费视频)

自从2010年开始&#xff0c;自从Lync Server 2010开始&#xff0c;我都在研究Lync 自动备份和批量管理用户&#xff0c;当年都做成功&#xff0c;做标准过&#xff0e;不过都是图片&#xff0c;未写博客&#xff0c;为什么呢?有可能你有这样那样的假设&#xff0c;但是今天可以…

数学很差的人能当程序员吗?

【CSDN 编者按】作者在大学时代受《程序员》杂志的启发&#xff0c;从数学专业投身计算机编程&#xff0c;毕业后进入软件开发行业。过去9年&#xff0c;他去过大厂敲代码&#xff0c;也曾在创业公司带过团队&#xff0c;一直从事“下一代”软件技术的研发&#xff0c;对于网上…

Nginx 学习笔记(六)引入线程池 性能提升9倍

原文地址&#xff1a;https://www.cnblogs.com/shitoufengkuang/p/4910333.html 一、前言 1、Nignx版本&#xff1a;1.7.11 以上 2、NGINX采用了异步、事件驱动的方法来处理连接。这种处理方式无需&#xff08;像使用传统架构的服务器一样&#xff09;为每个请求创建额外的专用…

Nginx源代码分析 - 日志处理

我看Nginx源代码的时候&#xff0c;感觉整个系统都在传递log指针。log在nginx里是比较关键的。日志和内存分配是最基础的两个起点代码&#xff0c;最好是在自己写的程序框架中早点完善并实现。以免未来要用大量的精力调整。1. 日志的源代码位置日志的源代码在src/code/ngx_log.…

strom.yaml配置

2019独角兽企业重金招聘Python工程师标准>>> 配置storm.yaml storm发行版在conf/storm.yaml包含了一些配置信息。你可以在这里看到默认配置。storm.yaml里面的配置比default.xml的优先级要高&#xff0c; 下面是要运行storm集群所必须的配置: 1. storm.zookeeper.se…

用 Python 快速制作海报级地图

作者&#xff1a;费弗里 来源&#xff1a;Python大数据分析 1 简介 基于Python中诸如matplotlib等功能丰富、自由度极高的绘图库&#xff0c;我们可以完成各种极富艺术感的可视化作品&#xff0c;关于这一点我在系列文章在模仿中精进数据可视化中已经带大家学习过很多案例了。 …

关于VS2012如何安装Windows Phone Toolkit

最近也是碰到很多问题&#xff0c;在编程的时候。这个问题是我遇到的比较棘手的一个&#xff0c;问了一堆人都说得很是模糊&#xff0c;最后还是琢磨出来了&#xff0c;深感欣慰。写下来以防以后忘记了怎么操作的&#xff0c;也期望能帮助到遇到同样问题的你。 首先让我先说了几…

论Oracle 11g数据库备份与恢复策略

11G中有个新特性&#xff0c;当表无数据时&#xff0c;不分配segment&#xff0c;以节省空间解决方案&#xff1a;1、insert一行&#xff0c;再roolback就会产生segment了该方法是在空表中插入一行数据&#xff0c;再删除&#xff0c;就会产生segment。则在数据库导出时可以导出…

使Apache实现gzip压缩

众所周知&#xff0c;在HTTP1.1中支持gzip压缩&#xff0c;这样可以缩小页面的容量从而加快页面的显示速度。可以使用常用HTTP抓包工具来检测一下你的站点是否开始了gzip压缩。 Apache默认的http.conf配置文件中没有开启gzip压缩&#xff0c;apache1.3.x可以用mod_gzip进行优化…