告别 if 地狱:Spring Boot 3 + QueryDSL 优雅实现动态分页查询

简介

QueryDSL插件不由Spring官方提供,而是一个独立的开源项目。不过Spring生态(Spring Data JPA)提供了对QueryDSL良好集成支持。QueryDSL 是一款用于构建类型安全的 SQL/JPQL 查询的开源框架。它通过纯Java API的方式,让开发者能够以面向对象的方式来构建数据库查询,从而替代传统的字符串拼接 SQL 或复杂的 Criteria API。

形象地举个例子,普通编写查询需要编写一大堆where条件语句,而且必须适应不同的查询条件搭配,比如一张表中包括:年龄、用户名、生日、邮箱、电话号,有的使用者喜欢以生日加姓名查询,而有的使用者喜欢以邮箱加电话号查询,可见在用户需求中查询条件组合多种多样,无论是使用Mybatis还是spring data jpa,在不使用QueryDSL的前提下,需要在mapper.xmlrepository中的SQL中写入大量查询语句,这显然非常繁琐。而QueryDSL正是为解决此问题而生。本文基于springboot 3.0记述使用方式。

pom.xml引入

xml 复制代码
<!-- QueryDSL依赖 -->
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <version>5.0.0</version>
    <classifier>jakarta</classifier>
</dependency>
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <version>5.0.0</version>
    <classifier>jakarta</classifier>
    <scope>provided</scope>
</dependency>
...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <annotationProcessorPaths>
            <path>
                <groupId>com.querydsl</groupId>
                <artifactId>querydsl-apt</artifactId>
                <version>5.0.0</version>
                <classifier>jakarta</classifier>
            </path>
            <path>
                <groupId>jakarta.persistence</groupId>
                <artifactId>jakarta.persistence-api</artifactId>
                <version>3.1.0</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

然后执行:mvn clean compile,最后在项目的target/generated-sources/annotations路径下找到以Q+entity名称的java类

Repository 怎么写?

继承QuerydslPredicateExecutor类

java 复制代码
package cn.train.repository;

import cn.train.entity.Users;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;

import java.util.UUID;

@Repository
public interface UsersRepository extends JpaRepository<Users, UUID>,QuerydslPredicateExecutor<Users> {
}

查询条件怎么装?

一共分3步走,我们一步一步讲解

第一步:创建一个Query类

这个得自己创建,没法自动生成,用于接收前端传入的查询条件

java 复制代码
@Data
public class UserQuery {
    private String username;
    private String sex;
    private Date birthdayStart;
    private Date birthdayEnd;
}

第二步:Service 里拼条件,顺便把分页加进去

java 复制代码
public Page<Users> queryAll(UserQuery query, PageRequest pageRequest) {
QUsers u = QUsers.users;
BooleanBuilder where = new BooleanBuilder();

if (q.getUsername() != null) {
    where.and(u.username.contains(q.getUsername()));
}
if (q.getSex() != null) {
    where.and(u.sex.eq(q.getSex()));
}
if (q.getBirthdayStart() != null && q.getBirthdayEnd() != null) {
    where.and(u.birthday.between(q.getBirthdayStart(), q.getBirthdayEnd()));
}
  // 加入分页
Page<Users> page = usersRepository.findAll(where,pageRequest);
return page;
}

第三步:controller接前台传入的条件

java 复制代码
@GetMapping("/query")
public ResponseEntity<Page<Users>> query(
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "10") int size,
        UserQuery userQuery // 这里特别注意不能写@RequestParam
) {
    return ResponseEntity.ok(usersService.queryAll(userQuery, PageRequest.of(page - 1, size)));
}

最后前台以/query?username=admin&sex=男&page=1&size=10类似格式传入查询即可

相关推荐
wuqingshun3141591 小时前
如何理解Spring Boot中的starter?
java·spring boot·后端
wuqingshun3141591 小时前
SpringBoot是如何实现自动配置的
java·spring boot·后端
zhouhui0011 小时前
AI帮我写了个Spring Boot校验,线上漏掉了这组边界条件
java·spring boot·redis·ai编程
hdsoft_huge1 小时前
SpringBoot系列17:日志体系Logback配置,日志分割、脱敏、异常堆栈收集规范(生产级落地)
java·spring boot·logback
吃饱了得干活1 小时前
扫码登录如何实现?从原理到实战
java·spring boot·redis
凤山老林2 小时前
数据库连接池深度调优:Spring Boot + HikariCP 泄漏检测、参数调优与慢 SQL 拦截体系
数据库·spring boot·sql
音符犹如代码17 小时前
后端视角看 EventBus:发布订阅总线的原理、场景与用法
java·spring boot·guava
Devin~Y21 小时前
互联网大厂Java面试实战:Spring Boot、MyBatis、Redis、Kafka、JWT、Spring Cloud 与 AI 场景追问
java·spring boot·redis·spring cloud·kafka·mybatis·spring security
何中应1 天前
Spring Boot整合Doris
java·数据库·spring boot
liudashuang20171 天前
SpringBoot监控及Dubbo服务优化总结
spring boot·后端·dubbo