1. 简介
本文将探讨如何在 Spring Boot 应用中使用 Blaze Persistence 库。该库提供了丰富的 Criteria API,用于以编程方式构建 SQL 查询,支持添加各类过滤器、函数和逻辑条件。我们将涵盖项目配置、查询构建示例以及实体到 DTO 的映射实现。
2. Maven 依赖
在 pom.xml
中添加以下核心依赖:
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-core-api-jakarta</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-core-impl-jakarta</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-hibernate-6.2</artifactId>
<scope>runtime</scope>
</dependency>
⚠️ 注意:Hibernate 版本不同时,最后一个依赖可能需要调整。
3. 实体模型
定义两个通过一对多关联的实体类 Person
和 Post
,使用 Hibernate 自动建表:
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
private int age;
@OneToMany(mappedBy = "author")
private Set<Post> posts = new HashSet<>();
}
@Entity
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
private String content;
@ManyToOne(fetch = FetchType.LAZY)
private Person author;
}
4. Criteria API
作为 JPA Criteria API 的替代方案,Blaze Persistence 设计更友好易用,且支持多种 JPA 实现。
4.1. 配置
在配置类中声明 CriteriaBuilderFactory
Bean:
@Autowired
private EntityManagerFactory entityManagerFactory;
@Bean
public CriteriaBuilderFactory createCriteriaBuilderFactory() {
CriteriaBuilderConfiguration config = Criteria.getDefault();
return config.createCriteriaBuilderFactory(entityManagerFactory);
}
4.2. 基础查询
两行代码即可完成全表查询:
List<Post> posts = builderFactory.create(entityManager, Post.class).getResultList();
✅ 关键点:
Post.class
参数同时定义了:- 查询结果类型
- 隐式查询根
- 自动生成
SELECT
和FROM
子句
生成的 JPQL:
SELECT post
FROM Post post;
4.3. WHERE 子句
通过链式调用添加条件,筛选年龄 18-40 岁且发表至少 2 篇文章的作者:
CriteriaBuilder<Person> personCriteriaBuilder = builderFactory.create(entityManager, Person.class, "p")
.where("p.age")
.betweenExpression("18")
.andExpression("40")
.where("SIZE(p.posts)").geExpression("2")
.orderByAsc("p.name")
.orderByAsc("p.id");
✅ 优势:
- 直接支持函数调用(如
SIZE
) - 通过
whereOr
/whereAnd
构建复合条件
复合条件示例(标题或作者名匹配):
CriteriaBuilder<Post> postCriteriaBuilder = builderFactory.create(entityManager, Post.class, "p")
.whereOr()
.where("p.title").like().value(title + "%").noEscape()
.where("p.author.name").eq(authorName)
.endOr();
4.4. FROM 子句
显式指定查询根可覆盖隐式设置:
CriteriaBuilder<Post> postCriteriaBuilder = builderFactory.create(entityManager, Post.class)
.from(Person.class, "person")
.select("person.posts");
此时 Post.class
仅定义返回类型,生成的 SQL 会自动添加 JOIN:
SELECT posts_1
FROM Person person
LEFT JOIN person.posts posts_1;
5. Entity-View 模块
解决实体与 DTO 的高效映射问题,通过接口定义投影结构。
5.1. Maven 依赖
添加以下依赖:
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-entity-view-api-jakarta</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-entity-view-impl-jakarta</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-entity-view-processor-jakarta</artifactId>
</dependency>
5.2. 配置
声明 EntityViewManager
Bean:
@Bean
public EntityViewManager createEntityViewManager(
CriteriaBuilderFactory criteriaBuilderFactory, EntityViewConfiguration entityViewConfiguration) {
return entityViewConfiguration.createEntityViewManager(criteriaBuilderFactory);
}
⚠️ 作用域需与 EntityManagerFactory
保持一致。
5.3. 映射定义
基础视图接口示例:
@EntityView(Post.class)
public interface PostView {
@IdMapping
Long getId();
String getTitle();
String getContent();
}
✅ 最佳实践:
- 使用
@EntityView
注解绑定实体类 - 通过
@IdMapping
优化equals
/hashCode
实现
自定义映射示例(标题大写):
@Mapping("UPPER(title)")
String getTitle();
扩展视图(包含作者信息):
@EntityView(Person.class)
public interface PersonView {
@IdMapping
Long getId();
int getAge();
String getName();
}
@EntityView(Post.class)
public interface PostWithAuthorView extends PostView {
PersonView getAuthor();
}
查询应用示例:
CriteriaBuilder<Post> postCriteriaBuilder = builderFactory.create(entityManager, Post.class, "p")
.whereOr()
.where("p.title").like().value("title%").noEscape()
.where("p.author.name").eq(authorName)
.endOr();
CriteriaBuilder<PostWithAuthorView> postWithAuthorViewCriteriaBuilder =
viewManager.applySetting(EntityViewSetting.create(PostWithAuthorView.class), postCriteriaBuilder);
生成的优化 SQL:
SELECT p.id AS PostWithAuthorView_id,
p.author.id AS PostWithAuthorView_author_id,
author_1.age AS PostWithAuthorView_author_age,
author_1.name AS PostWithAuthorView_author_name,
p.content AS PostWithAuthorView_content,
UPPER(p.title) AS PostWithAuthorView_title
FROM com.baeldung.model.Post p
LEFT JOIN p.author author_1
WHERE p.title LIKE REPLACE(:param_0, '\\', '\\\\')
OR author_1.name = :param_1
5.4. 集成 Spring Data
添加 Spring Data 集成依赖:
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-spring-data-3.1</artifactId>
</dependency>
配置类添加注解:
@EnableBlazeRepositories(basePackages = "com.example.repository")
Repository 接口定义:
@Repository
@Transactional(readOnly = true)
public interface PostViewRepository extends EntityViewRepository<PostWithAuthorView, Long> {
}
✅ 继承 EntityViewRepository
后自动获得 findAll
、findOne
等常用方法。
6. 总结
本文演示了 Blaze Persistence 的核心配置与查询构建技巧。该库通过简洁的 API 设计和强大的映射能力,有效解决了传统 JPA Criteria API 的痛点。完整示例代码可在 GitHub 获取。