Springboot使用queryDSL

一、简介

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

JPA操作多表操作的时候,很麻烦,我们也可以建关联关系,但是需要维护一对关系,序列化的问题,JPA的单表操作也很麻烦,不然就得写SQL语句,一点都不灵活。非常怀念MyBatis-plus,所幸找到了QueryDSL这个Java框架,大大的简化了JPA查询的复杂度。

下面就是一个操作JPA单表复杂查询

/**
* 组装条件查询
*
* @param companyReq
* @return
*/
private Specification selectCompanyCondition(CompanyReq companyReq) {
return new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = Lists.newArrayList();
// 英文简称
if (!StringUtils.isEmpty(companyReq.getCompanyCode())) {
predicates.add(criteriaBuilder.equal(root.get("companyCode"), companyReq.getCompanyCode()));
}
// 企业域名
if (!StringUtils.isEmpty(companyReq.getCompanyDNS())) {
predicates.add(criteriaBuilder.equal(root.get("companyDNS"), companyReq.getCompanyDNS()));
}
// 英文全称
if (!StringUtils.isEmpty(companyReq.getCompanyFullCode())) {
predicates.add(criteriaBuilder.equal(root.get("companyFullCode"), companyReq.getCompanyFullCode()));
}
// 企业简称
if (!StringUtils.isEmpty(companyReq.getCompanyName())) {
predicates.add(criteriaBuilder.like(root.get("companyName"), "%" + companyReq.getCompanyName() + "%"));
}
// 注册时间 时间段之内
if ((companyReq.getCreateEndTime() != null) && (companyReq.getCreateStartTime() != null)) {
predicates.add(criteriaBuilder.between(root.get("createTime"), companyReq.getCreateStartTime(), companyReq.getCreateEndTime()));
}
// 按照创建时间排序 默认为 不传该字段 或者 rankType = true 为 降序
if (companyReq.getRankType() == null || companyReq.getRankType()) {
query.orderBy(criteriaBuilder.desc(root.get("createTime")));
} else {
query.orderBy(criteriaBuilder.asc(root.get("createTime")));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
}

并且在不是很想加关联关系,但是想做关联查询。就很无奈了,我并没有找到好的方法区处理。QueryDSL就可以很好地处理。下面开始介绍!

二、添加依赖

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

三、添加maven插件

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!-- 插件失败:将{JAVA_HOME}/lib/tools.jar 复制到 jre/lib 目录下 -->
<!-- 插件如果还是飘红,无所谓,无视就可以 -->
<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>

Springboot之QueryDSL增强JPA操作_List

四、添加QueryDSL的配置类

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;

/**
* @author 墨龙吟
* @version 1.0.0
* @ClassName QueryDSLConfig.java
* @Email 2354713722@qq.com
* @Description TODO
* @createTime 2019年08月27日 - 19:52
*/
@Configuration
public class QueryDSLConfig {

@Autowired
private EntityManager entityManager;

@Bean
public JPAQueryFactory getQueryFactory() {
return new JPAQueryFactory(entityManager);
}

}

五、实例使用

在操作Service类中注入JPAQueryFactory

@Autowired
private JPAQueryFactory queryFactory;

然后就可以操作了数据表了。

where和orderBy使用:

@Override
public List<FileEntity> getAll() {
QFileEntity qFileEntity = QFileEntity.fileEntity;
return queryFactory.selectFrom(qFileEntity)
.where(qFileEntity.canView.eq(true))
.orderBy(qFileEntity.createTime.desc())
.fetch();
}

多表联查,返回指定的字段

@Override
public List<FileVO> getFileList() {
QFileEntity qFileEntity = QFileEntity.fileEntity;
QUserEntity qUserEntity = QUserEntity.userEntity;
List<FileVO> result = queryFactory
.select(Projections.bean(
FileVO.class,
qFileEntity.fileUrl,
qFileEntity.fileName,
qFileEntity.fileId,
qFileEntity.updateTime,
qFileEntity.createTime,
qFileEntity.userId,
qFileEntity.brief,
qUserEntity.userName,
qFileEntity.isDefault
))
.from(qFileEntity)
.leftJoin(qUserEntity)
.on(qFileEntity.userId.eq(qUserEntity.userId))
.where(qFileEntity.canView.eq(true))
.orderBy(qFileEntity.createTime.desc())
.fetch();
return result;
}

直接返回实体类

@Override
public List<UserEntity> checkUserInfo(String username) {
QUserEntity qUserEntity = QUserEntity.userEntity;
return queryFactory
.selectFrom(qUserEntity)
.where(qUserEntity.userName.eq(username).and(qUserEntity.canView.eq(true)))
.fetch();
}

六、总结

QueryDSL 操作数据表做复杂查询是非常棒的。具体细节到​​官网​​查看吧

关注一个个人微信公众号吧!感谢!

Springboot之QueryDSL增强JPA操作_List_02