1、概览 本文将扩展 上一篇文章 中实现的高级搜索操作,在 REST API 查询语言中加入基于 OR 的搜索条件。
2、实现方法 以前,search 查询参数中的所有条件都是由 AND 运算符组成的条件。
现在,使用标志来指示必须使用 OR 运算符组合条件。
http://localhost:8080/users?search=firstName:john,'lastName:doe 注意,这里用单引号标记了条件 lastName,以示区别。我们会在条件值对象 SpecSearchCriteria 中捕获 OR 运算符的 Predicate:
public SpecSearchCriteria( String orPredicate, String key, SearchOperation operation, Object value) { super(); this.orPredicate = orPredicate != null && orPredicate.equals(SearchOperation.OR_PREDICATE_FLAG); this.key = key; this.operation = operation; this.value = value; } 3、改进 UserSpecificationBuilder 修改 UserSpecificationBuilder,以在构建 Specification<User> 时考虑 OR 条件:
public Specification<User> build() { if (params.size() == 0) { return null; } Specification<User> result = new UserSpecification(params.
1、概览 前面几篇文章介绍了三种 REST 查询语言的实现方式,分别是:JPA Criteria、Spring Data JPA Specification 和 QueryDSL。
本文将扩展前面几篇文章中开发的 REST 查询语言,使其包含更多搜索操作,如:等于、不等于、大于、小于、前缀、后缀、包含和类似(Like)。
本文选择使用 Specification,因为它是一种清晰而灵活的表示操作的方式。
2、SearchOperation 枚举 首先,通过枚举来更好地定义各种支持的搜索操作:
public enum SearchOperation { EQUALITY, NEGATION, GREATER_THAN, LESS_THAN, LIKE, STARTS_WITH, ENDS_WITH, CONTAINS; public static final String[] SIMPLE_OPERATION_SET = { ":", "!", ">", "<", "~" }; public static SearchOperation getSimpleOperation(char input) { switch (input) { case ':': return EQUALITY; case '!': return NEGATION; case '>': return GREATER_THAN; case '<': return LESS_THAN; case '~': return LIKE; default: return null; } } } 有两组操作:
Java 16 中引入的 Java Record 允许轻松地定义数据类(Data Class),这非常适合用于 JPA 中的投影查询。
Record 不能作为实体类 Record 只能用于投影查询。像 Hibernate 等流行的 JPA 实现创建代理对象时需要无参构造函数、非 final 字段、setter 方法和非 final 的实体类。而这些特性在 Record 中要么被不鼓励使用,要么被明确禁止使用。
Record 和 JPA 如果你在应用中直接使用 JPA,有几种不同的方法可以将记 Record 整合到 DAO 层中。
CriteriaBuilder Record 可与 CriteriaBuilder 一起使用,如下:
public List<AdvocateRecord> findAllWithCriteriaBuilder() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<AdvocateRecord> cq = cb.createQuery(AdvocateRecord.class); Root<AdvocateEntity> root = cq.from(AdvocateEntity.class); cq.select(cb.construct( AdvocateRecord.class, root.get("id"), root.get("fName"), root.get("lName"), root.get("region"), root.get("twitterFollowers"))); TypedQuery<AdvocateRecord> q = em.createQuery(cq); return q.getResultList(); } TypedQuery Record 也可以与 TypedQuery 一起使用,但需要在 JPQL 查询中提供完整类路径的构造函数。
1、概览 在本教程中,我们将探讨如何在 JPA 中使用 Java Record,包括以下内容。
为什么 Record 不能作为 Entity 使用。 在 JPA 中使用 Record。 在 Spring Boot 应用中使用 Spring Data JPA 和 Record。 2、Record 和 Enttiy Record 是不可变的,用于存储数据。它们包含字段、全参数构造函数、getter、toString 和 equals/hashCode 方法。由于它们是不可变的,因此没有 setter。由于其语法简洁,在 Java 中经常被用作数据传输对象(DTO)。
Entity(实体)是映射到数据库表的类。它们用于表示数据库中的条目。它们的字段被映射到数据库表中的列。
2.1、Record 不能作为 Entity 实体由 JPA provider 处理。JPA provider 负责创建数据库表,将实体映射到表,并将实体持久化到数据库。在流行的 JPA provider(如 Hibernate)中,实体是使用代理来创建和管理的。
代理是在运行时生成并继承实体类的类。这些代理依赖于实体类的无参数构造函数和 setter。由于 Record 不具有这些,所以它们不能用作实体。
2.2、在 JPA 中使用 Record 的其他方法 由于在 Java 中使用 Record 的简便性和安全性,在 JPA 中以其他方式使用 Record 可能是有益的。
在 JPA中,我们可以通过以下方式使用 Record:
将查询结果转换为 Record。 使用 Record 作为DTO在各个层之间传输数据。 将实体转换为 Record。 3、项目设置 我们将使用 Spring Boot 创建一个使用 JPA 和 Spring Data JPA 的简单应用程序。然后,我们将了解在与数据库交互时使用 Record 的几种方法。