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
JPA 复杂查询 - Querydsl相关推荐
- jpa 动态查询条件 数组_Spring data jpa 复杂动态查询方式总结
一.Spring data jpa 简介 首先JPA是Java持久层API,由Sun公司开发, 希望整合ORM技术,实现天下归一. 诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,目前也是 ...
- jpa中::::_项目学生:JPA标准查询
jpa中:::: 这是Project Student的一部分. 其他职位包括带有Jersey的Webservice Client,带有Jersey的 Webservice Server , 业务层 , ...
- 项目学生:JPA标准查询
这是Project Student的一部分. 其他职位包括带有Jersey的Webservice Client,带有Jersey的 Webservice Server , 业务层 , 具有Spring ...
- jpa分页查询_spring data jpa 居然提供了这么多查询方式!
spring data jpa提供了多种查询方式,如下: 方法名称查询 继承Repository接口 测试代码 方法名称中支持的关键字(官方文档提供) 使用JPA命名查询 在User实体中定义jpql ...
- Spring data jpa 条件查询-按时间段查询
Spring data jpa 条件查询-按时间段查询 @Overridepublic Page<泛型> findRecordList(int couponDetailId, int pa ...
- Spring Boot JPA的查询语句
文章目录 准备工作 Containing, Contains, IsContaining 和 Like StartsWith EndsWith 大小写不敏感 Not @Query Spring Boo ...
- jpa的查询api_为JPA的本机查询API键入安全查询
jpa的查询api 当您使用JPA时-有时-JPQL不能解决问题,您将不得不使用本机SQL. 从一开始,像Hibernate这样的ORM就为这些情况保留了开放的"后门",并为Spr ...
- Spring Boot+JPA 有查询条件的查询
本篇介绍使用JPA 的条件查询, 关于JPA基本查询可以参考: Spring Boot+JPA 查询数据方式与代码演示 不安全的查询 在开发时, 为了简便, 习惯会拼接Where子句的查询条件, 查询 ...
- JPA criteria 查询:类型安全与面向对象
序言 自工作以来,除了以前比较流量的hibernate,就是一直使用ORM 规范 JPA了.而这几天工作需要,研究了下JPA的标准查询,名为:JPA criteria查询.相比JPQL,其优势是类型安 ...
最新文章
- windows缩放200模糊_1.8M超轻量目标检测模型NanoDet,比YOLO跑得快,上线两天Star量超200...
- 合并远程仓库到本地_使用命令行把你新建的项目上传到GitHub仓库中
- asp.net mvc 实现文件管理参考资料
- H1作业(字符串和字节串)
- ADO.NET数据访问方式:SqlDataReader
- JavaParser使用指南
- python前端和后端_python是用于前端还是后端开发
- R如何导入带有分隔符号的文件
- 【白皮书】以太坊 (Ethereum ):下一代智能合约和去中心化应用平台
- C++实现双人枪战游戏
- 如何看待腾讯云电子签呢?
- 基于redis实现的分布式时间序列存储Roshi
- jQuery取消checkbox选中状态
- 【人工智能】知识表示
- 图像质量评价数据库与图像质量算法性能评价指标
- 字典(dict),增删改查,嵌套
- Linux嵌入式驱动开发零基础入门集合(STM32过渡到Linux嵌入式)
- 家装灯线走线图_家装照明线路走线方法
- iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总,icloudpassbook...
- 这两款软件让你实现把手机屏幕变成提词器
热门文章
- mouseover与mouseenter,mouseout与mouseleave的区别
- 2017.1.9版给信息源新增:max_len、max_db字段
- javascript中重要概念-闭包-深入理解
- redis cluster 安装配置
- cassandra命令
- js中document.write的那点事
- MIT开发新加密货币,用户所需数据比比特币减少99%
- Linux I2C工具查看配置I2C设备【转】
- Marathon 0.15: 更稳定 更多数据 更易用
- Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入) 转