添加依赖

    <!--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 {
@Autowired
private UserRepositoryDls repository; @Autowired
@PersistenceContext
private EntityManager entityManager; private JPAQueryFactory queryFactory; @PostConstruct
public 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
@PersistenceContext
private EntityManager entityManager; private JPAQueryFactory queryFactory; @PostConstruct
public 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
@PersistenceContext
private EntityManager entityManager; private JPAQueryFactory queryFactory; @PostConstruct
public 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 处理复杂的操作

JPA 复杂查询 - Querydsl的更多相关文章

  1. Spring JPA 定义查询方法

    Spring JPA 定义查询方法 翻译:Defining Query Methods ​ 存储库代理有两种方式基于方法名派生特定域的查询方式: 直接从方法名派生查询 自定义查询方式 ​ 可用选项基于 ...

  2. Spring Data JPA 简单查询--接口方法

    一.接口方法整理速查 下表针对于简单查询,即JpaRepository接口(继承了CrudRepository接口.PagingAndSortingRepository接口)中的可访问方法进行整理.( ...

  3. spring data jpa 分页查询

    https://www.cnblogs.com/hdwang/p/7843405.html spring data jpa 分页查询   法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特 ...

  4. 第11章—使用对象关系映射持久化数据—SpringBoot+SpringData+Jpa进行查询修改数据库

    SpringBoot+SpringData+Jpa进行查询修改数据库 JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分.但它又不限于EJB 3.0,你可以在Web应用.甚至桌面应用 ...

  5. JPA criteria 查询:类型安全与面向对象

    参考:https://my.oschina.net/zhaoqian/blog/133500 一.JPA元模型概念,及使用 在JPA中,标准查询是以元模型的概念为基础的.元模型是为具体持久化单元的受管 ...

  6. spring data jpa 动态查询(工具类封装)

    利用JPA的Specification<T>接口和元模型就实现动态查询了.但是这样每一个需要动态查询的地方都需要写一个这样类似的findByConditions方法,小型项目还好,大型项目 ...

  7. springboot整合spring data jpa 动态查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...

  8. springboot集成Spring Data JPA数据查询

    1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...

  9. spring data JPA entityManager查询 并将查询到的值转为实体对象

    spring data JPA entityManager查询 并将查询到的值转为实体对象 . https://blog.csdn.net/qq_34791233/article/details/81 ...

随机推荐

  1. 使用Python切片赋值

    解释器下运行以下代码:list1 = [4,5,6,7,8,9] list1[2:5] = ['a','b','c']结果是:[4, 5, 'a', 'b', 'c', 9]

  2. 【问题记录】— web页面调用本地程序

    起因: 最近由于项目需要在web页面中调用本地部署的exe程序:进而对该功能实现做了对应了解:以及存在的问题进行记录. 要实现该功能就不得不说浏览器自定义协议:解决办法:那么它是什么呢? 浏览器自定义 ...

  3. web端项目如何测试

    1.是否支持各种网络 2.网络如果演示能否正常加载 3.加载时断网还能加载出来么 4.浏览时断网页面是否保持 5.是否兼容各种不同的浏览器 6.不同的浏览器加载出的页面是否一致 7.页面效果如何 8. ...

  4. Clickhouse 入门

    clickhouse 简介 ck是一个列式存储的数据库,其针对的场景是OLAP.OLAP的特点是: 数据不经常写,即便写也是批量写.不像OLTP是一条一条写 大多数是读请求 查询并发较少,不适合放置先 ...

  5. vue上传视屏或者图片到七牛云

    首先下载七牛云的JavaScript-SDK npm install qiniu-js 下载完成JavaScript-SDK以后就可以上传图片信息了 <template> <div& ...

  6. 团队作业4-Day6

    团队作业4-Day6 项目git地址 1. 站立式会议 2. 项目燃尽图 3. 适当的项目截图 4. 代码/文档签入记录(部分) 5. 每人每日总结 吴梓华:今日修复了图片显示BUG,补充了排位模式出 ...

  7. v-lazyload数据变化图片不切换

    这个问题让我很困惑,明明得到的商品数据已经改变了,但是就图片不变化,随后找到了解决办法,那就是多加一个动态的key <img v-lazy="item.productImage&quo ...

  8. 串口数据监视 Serial Port Monitor

    串口数据监视工具 Serial Port Monitor可以在其它应用读写串口时监视串口数据, 很好用,但只有15天试用期.

  9. Java-web-多个独立项目之间相互调用实践

    本篇文章只涉及到应用层面,没有涉及到什么底层原理之类的,我目前的实力还没有达到那个级别.如果是大神级别的人看到这篇文章,请跳过. 项目框架也已经是搭建好了的,springboot版本为1.5,数据库操 ...

  10. NetCDF格式.nc

    netcdf sfc_pres_temp { dimensions: latitude = 6 ; //纬度轴 longitude = 12 ; //经度轴 variables: float lati ...