QueryDSL进行简单的分页查询

前言

自己写的一个后台管理系统,在多条件查询客户信息时需要进行分页处理,如果用MyBatis的话,PageHelper插件就挺好用的,但是既然用了QueryDSL来进行查询操作的话,就用它的方法进行分页。

查询实体类创建

先创建一个客户实体类Client,对应数据库里的client表,里面是客户信息的属性

@Data
@Entity
@Table(name="client")
public class Client implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "clientId")
    private int clientId;
    @Column(name = "clientName")
    private String clientName;
    @Column(name = "address")
    private String address;
    @Column(name = "cardId")
    private String cardId;
    @Column(name = "birthday")
    private String birthday;
    @Column(name = "createDate")
    private String createDate;
    @Column(name = "clientType")
    private String clientType;
    @Column(name = "phone")
    private String phone;
    @Column(name = "eMail")
    private String eMail;
    @Column(name="clientNo")
    private String clientNo;
    @Column(name="status")
    private int status;
}

查询实体类设计

既然包含条件查询,需要把查询条件封装成一个新的类,在controller层接收,然后传给Service层进行处理,具体如下:

@Data
public class ClientReq {
    private String clientNo;  //客户号
    private String clientName; //客户名
    private String cardId; //证件号
    private String startDate; //起始日期(范围查询生日)
    private String endDate;//截止日期(范围查询生日)
    private String clientType;//客户类型
    private String phone;
    private long pageNum=1;//当前页数(默认为1)
    private long pageSize=5;//每页数量(默认为5)
}

多条件分页查询的实现

多条件分页查询在Service层实现,因为使用QueryDSL实现,需要两个类:EntityManager和JPAQueryFactory,并且JPAQueryFactory在需要使用@PostConstructz注解标记,进行初始化,代码如下

private JPAQueryFactory jpaQueryFactory;
    @Autowired
    private EntityManager entityManager;
    @PostConstruct
    public void initFactory(){
        jpaQueryFactory = new JPAQueryFactory(entityManager);
    }

之后就是实现分页条件查询的方法,因为涉及多条件判断,前端传来的筛选条件可能有空的字段,所以需要使用BooleanBuilder类进行动态的条件筛选,这里单独封装一个方法,用来判断筛选条件哪些为空,并且将不为空的判断条件加入到sql中,具体实现如下:

public void checkCondition(BooleanBuilder booleanBuilder,QClient qClient,ClientReq clientReq){
        if(!StringUtils.isEmpty(clientReq.getClientName()))
            booleanBuilder.and(qClient.clientName.contains(clientReq.getClientName()));
        if(!StringUtils.isEmpty(clientReq.getClientNo()))
            booleanBuilder.and(qClient.clientNo.contains(clientReq.getClientNo()));
        if(!StringUtils.isEmpty(clientReq.getCardId()))
            booleanBuilder.and(qClient.cardId.contains(clientReq.getCardId()));
        if(!StringUtils.isEmpty(clientReq.getClientType()))
            booleanBuilder.and(qClient.clientType.contains(clientReq.getClientType()));
        if(!StringUtils.isEmpty(clientReq.getPhone()))
            booleanBuilder.and(qClient.phone.contains(clientReq.getPhone()));
        if(clientReq.getStartDate()!=null&&clientReq.getEndDate()!=null)
            booleanBuilder.and(qClient.birthday.between(clientReq.getStartDate(),clientReq.getEndDate()));
}

最后就是核心代码,分页查询的实现了,很简单,几行就结束了

 public Map<String,Object> queryClientByRequire(ClientReq clientReq) {
        QClient qClient = QClient.client;
        HashMap<String, Object> result = new HashMap<>();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        checkCondition(booleanBuilder,qClient,clientReq);
        long count = jpaQueryFactory.select(qClient.count()).from(qClient).
                where(booleanBuilder).fetchOne();
        List<Client> clientList = jpaQueryFactory.select(qClient).
                from(qClient).
                where(booleanBuilder).
                orderBy(qClient.clientId.asc()).
                offset((clientReq.getPageNum()-1)*clientReq.getPageSize()).
                limit(clientReq.getPageSize()).
                fetch();
        result.put("clientList",clientList);
        result.put("sum",count);
        return result;
    }

QueryDSL的语法还是很好理解的,就像是把方法拼装成SQL语句,其中offset()表示从第几页开始查,limit()表示查询条数,最后fetch()方法会返回对应泛型的List,即查询的数据,而另一个count记录了查询的条数,用来返回给前端做处理。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。