简介
QueryDSL插件不由Spring官方提供,而是一个独立的开源项目。不过Spring生态(Spring Data JPA)提供了对QueryDSL良好集成支持。QueryDSL 是一款用于构建类型安全的 SQL/JPQL 查询的开源框架。它通过纯Java API的方式,让开发者能够以面向对象的方式来构建数据库查询,从而替代传统的字符串拼接 SQL 或复杂的 Criteria API。
形象地举个例子,普通编写查询需要编写一大堆where条件语句,而且必须适应不同的查询条件搭配,比如一张表中包括:年龄、用户名、生日、邮箱、电话号,有的使用者喜欢以生日加姓名查询,而有的使用者喜欢以邮箱加电话号查询,可见在用户需求中查询条件组合多种多样,无论是使用Mybatis还是spring data jpa,在不使用QueryDSL的前提下,需要在mapper.xml或repository中的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类似格式传入查询即可