相信很多人在做订单管理的时候会用到多条件的检索,比如说查询订单状态是已支付的,金额在100-200之间的商铺a的已完结的订单,这样的多条件。
实现方式有多种,核心就一个if和判空。今天学习了querydsl,来具体回顾一下。
首先是我做的效果图,我们主要看查询怎么实现的。
介绍一下querydsl
首先QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查询。
其次Querydsl可以通过一组通用的查询API为用户构建出适合不同类型ORM框架或者是SQL的查询语句,也就是说QueryDSL是基于各种ORM框架以及SQL之上的一个通用的查询框架。
再然后借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建查询。目前QueryDSL支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。
开始开发 ,首先是pom依赖
这里要加两个关于querydsl的依赖,jpa和apt,版本是一致的
com.querydsl
querydsl-jpa
4.2.1
com.querydsl
querydsl-apt
4.2.1
然后是要配置一个插件来生成Q版的实体类,只有Q版的实体类才能参与querydsl的查询
com.querydsl
querydsl-maven-plugin
generate-sources
jpa-export
target/generated-sources/java
com.jerry.gamemarket.entity
target/generated-sources/java 这是生成Q版实体的目标文件夹
com.jerry.gamemarket.entity 这是把那些包下的实体生成Q版。
在编写具体的查询方法之前我们需要实例化EntityManager对象以及JPAQueryFactory对象,并且通过实例化控制器时就去实例化JPAQueryFactory对象,所以在启动类中引入一个Bean叫JPAQueryFactory加一个EntityManager参数,可以全局使用。
@Bean
public JPAQueryFactory queryFactory(EntityManager entityManager){
return new JPAQueryFactory(entityManager);
}
搜索条件实体类
package com.jerry.gamemarket.dto;
import com.jerry.gamemarket.enums.OrderStatusEnums;
import com.jerry.gamemarket.enums.PayStatusEnums;
import lombok.Data;
import org.springframework.context.annotation.Bean;
import java.math.BigDecimal;
/**
* author by 李兆杰
* Date 2018/11/28
*/
@Data
public class SearchOrderDTO {
private String orderId;
// private String id;
private String buyerName;
private String buyerPhone;
private String buyerAddress;
private String canteenName;
private BigDecimal maxAmount;
private BigDecimal minAmount;
private Integer orderStatus;
// 默认未支付
private Integer payStatus;
private Integer pageNum = 1;
private Integer pageSize=10;
}
动态搜索实现类中的方法,这里返回类型是 QueryResults,我们了解一下这个特殊的返回类型
看源码
results是返回的list数据数组
total是总数
offset是从哪开始
limit是限制条数
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.querydsl.core;
import com.google.common.collect.ImmutableList;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Nullable;
public final class QueryResults implements Serializable {
private static final long serialVersionUID = -4591506147471300909L;
private static final QueryResults
@Override
public QueryResults dymamicQuery(SearchOrderDTO searchOrderDTO) {
QOrderMaster o = QOrderMaster.orderMaster;
JPAQuery query = jpaQueryFactory.select(o).from(o);
if (!StringUtils.isEmpty(searchOrderDTO.getOrderId())){
query.where(o.orderId.like(searchOrderDTO.getOrderId()));
}
if (!StringUtils.isEmpty(searchOrderDTO.getBuyerName())){
query.where(o.buyerName.like("%"+searchOrderDTO.getBuyerName()+"%"));
}
if (!StringUtils.isEmpty(searchOrderDTO.getBuyerPhone())){
query.where(o.buyerPhone.eq(searchOrderDTO.getBuyerPhone()));
}
if (searchOrderDTO.getMaxAmount()!=null && searchOrderDTO.getMinAmount()!=null){
query.where(o.orderAmount.goe(searchOrderDTO.getMinAmount()));
}
if (searchOrderDTO.getMaxAmount()!=null && searchOrderDTO.getMinAmount()!=null){
query.where(o.orderAmount.loe(searchOrderDTO.getMaxAmount()));
}
if (searchOrderDTO.getOrderStatus()!=null){
query.where(o.orderStatus.eq(searchOrderDTO.getOrderStatus()));
}
if (searchOrderDTO.getPayStatus()!=null){
query.where(o.payStatus.eq(searchOrderDTO.getPayStatus()));
}
return query.orderBy(o.createTime.desc())
.offset((searchOrderDTO.getPageNum()-1)*searchOrderDTO.getPageSize())
.limit(searchOrderDTO.getPageSize())
.fetchResults();
}
这些查询中包含了模糊查询,动态查询和分页
最后是Controller中的引用
@PostMapping("/searchorder")
public QueryResults findByCase(@RequestBody SearchOrderDTO searchOrderDTO){
QueryResults queryResults=orderService.dymamicQuery(searchOrderDTO);
System.out.println(searchOrderDTO);
System.out.println(queryResults.getResults());
return queryResults;
}
整个查询就完成了,怎么去渲染数据就看大家喜好了。文笔有限,欢迎吐槽,谢谢阅读