一、JPA Querydsl 简介
Querydsl是一个以类型安全和强类型查询查询框架工具,可以解决使用JPA进行复杂查询的难题,它可以直接与Spring Data JPA集成,使用Querydsl可以越过JPA接口,直接使用JPQL查询语言进行查询,其语法类似于SQL语言。在Spring Boot开发中使用Querydsl可以方便地进行代码生成和查询操作。
二、JPA Querydsl 代码生成
Querydsl提供了一个基于注解的代码生成工具,可以根据实体类生成查询类,这里我们以一个简单的User实体为例:
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
private String email;
// getter和setter方法
}
使用Querydsl提供的注解进行代码生成:
package com.example.demo.entity;
import com.querydsl.core.annotations.QueryEntity;
import javax.persistence.*;
@QueryEntity
@Entity
@Table(name = "user")
public class QUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
private String email;
// getter和setter方法
}
可以看到生成的QUser类与原User实体类对应,可以直接在查询中进行使用。在Spring Boot中,我们可以在pom.xml文件中添加以下配置:
<build>
<plugins>
...
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
使用 mvn clean compile 命令进行代码生成。生成的QUser类位于target/generated-sources/java目录下。
三、JPA Querydsl 基本查询
在Spring Boot项目中,需要在pom.xml文件中引入以下依赖:
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>4.4.0</version>
</dependency>
以下以User实体为例进行基本查询操作:
1、创建JPAQueryFactory实例:
@Autowired
private EntityManager entityManager;
private JPAQueryFactory queryFactory;
...
queryFactory = new JPAQueryFactory(entityManager);
2、使用查询类QUser进行查询:
① 查询所有数据:
List<User> userList = queryFactory
.selectFrom(QUser.user)
.fetch();
② 根据id查询单条数据:
User user = queryFactory
.selectFrom(QUser.user)
.where(QUser.user.id.eq(1L))
.fetchOne();
③ 排序查询:
List<User> userList = queryFactory
.selectFrom(QUser.user)
.orderBy(QUser.user.age.desc())
.fetch();
④ 分页查询:
Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "age"));
List<User> userList = queryFactory
.selectFrom(QUser.user)
.orderBy(QUser.user.age.desc())
.offset(pageable.getOffset()) // 起始位置
.limit(pageable.getPageSize()) // 每页条数
.fetch();
四、JPA Querydsl 高级查询
Querydsl提供了丰富的查询方法,以下列举几个常用的查询操作:
1、聚合查询:
使用Querydsl进行聚合查询可以直接使用SQL中的聚合函数,以下以查询最大年龄为例:
Integer maxAge = queryFactory
.select(QUser.user.age.max())
.from(QUser.user)
.fetchOne();
2、连接查询:
Querydsl支持多表连接查询,如果使用的是Spring Data JPA,可以直接使用以下方式进行关联查询:
@Query("SELECT u FROM User u JOIN u.department d WHERE d.name = :name")
List<User> findByDepartmentName(@Param("name") String name);
如果使用Querydsl进行关联查询,可以通过以下方式进行:
List<User> userList = queryFactory
.selectFrom(QUser.user)
.leftJoin(QUser.user.department, QDepartment.department)
.where(QDepartment.department.name.eq("IT"))
.fetch();
3、子查询:
Querydsl支持子查询,以下以查询年龄在平均年龄以上的用户为例:
NumberPath<Double> avgAge = Expressions.numberPath(Double.class, "avgAge");
List<User> userList = queryFactory
.selectFrom(QUser.user)
.where(QUser.user.age.gt(
JPAExpressions.select(QUser.user.age.avg())
.from(QUser.user))
)
.orderBy(QUser.user.age.desc())
.fetch();
五、JPA Querydsl 与Spring Data JPA 集成
使用Querydsl还可以与Spring Data JPA集成,这样可以方便地进行分页查询、动态查询等操作。以下以分页查询为例:
1、继承QuerydslPredicateExecutor:
public interface UserRepository extends JpaRepository<User, Long>, QuerydslPredicateExecutor<User> {
}
2、使用PageRequest进行分页查询:
Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "age"));
Predicate predicate = QUser.user.age.goe(18); // 查询条件
Page<User> userPage = userRepository.findAll(predicate, pageable);
六、JPA Querydsl 总结
使用Querydsl可以大大简化JPA的查询操作,可以方便地进行代码生成、基本查询、高级查询、与Spring Data JPA集成等操作。通过类型安全、强类型查询方式,可以大大提高开发效率和代码质量。使用Querydsl进行JPA查询操作是一种非常好的方法,值得程序员在项目中使用。