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>
四、添加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 [email protected]
* @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 操作數據表做複雜查詢是非常棒的。具體細節到官網查看吧
關注一個個人微信公衆號吧!感謝!