Spring Data JPA系列QueryByExampleExecutor使用详解

Spring Data JPA系列QueryByExampleExecutor使用详解

简介

Spring Data JPA 是 Spring Data 的一个模块,它通过 JPA 技术为程序开发人员提供了方便、快捷的持久化支持。Query By Example(QBE)是 Spring Data JPA 模块中的一部分,允许您根据已知的实体对象创建查询样例,可以通过 QBE 生成基于实体属性的动态查询语句。

QueryByExampleExecutor

QueryByExampleExecutor 接口提供了按实例的查询语法。该接口包含两个方法:

<S extends T> Optional<S> findOne(Example<S> example);
<S extends T> Iterable<S> findAll(Example<S> example);

其中,findOne() 方法将返回与示例符合的第一个实体。如果没有找到任何实体,则返回 Optional 的空实例。

findAll() 方法将根据示例返回一个 Iterable 集合。如果没有找到任何实体,则返回空的 Iterable 实例。

ExampleMatcher

ExampleMatcher 是 Query By Example 的核心部分,它描述了对特定类型的示例应如何进行匹配。 ExampleMatcher 可以在 Query 接口级别或在基础 CRUD Repository 接口级别对应用程序执行的查询进行全局配置。

ExampleMatcher.Builder 是用于实例化 ExampleMatcher 的静态构建器。

以下代码片段说明了如何构建 ExampleMatcher 对象:

ExampleMatcher matcher = ExampleMatcher.matching()
        .withIgnorePaths("field1", "field2")
        .withMatcher("field3", matcher -> matcher.startsWith())
        .withMatcher("field4", matcher -> matcher.endsWith())
        .withMatcher("field5", matcher -> matcher.contains())
        .withMatcher("field6", matcher -> matcher.matches());

上述 ExampleMatcher 会执行以下操作:

  • 忽略名为 field1 和 field2 的属性。
  • 特定字段应以其字段值开头筛选。
  • 特定字段应以其字段值结尾。
  • 特定字段应包含其字段值。
  • 特定字段应具有与其字段值完全匹配的值。

示例1 方法级别

考虑以下 Entity:

@Entity
@Table(name = "employee")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_id", nullable = false)
    private Department department;

    // ... 省略其他字段和方法
}

现在我们想按名称模糊搜索 Employee,请使用 QBE 实现此目的。

Employee employee = new Employee();
employee.setName("mark");
ExampleMatcher matcher = ExampleMatcher.matching()
        .withMatcher("name", match -> match.contains());
Example<Employee> example = Example.of(employee, matcher);
List<Employee> employees = employeeRepository.findAll(example);

上面的示例将返回符合 name 属性包含“mark”子字符串的 Employee 实例的所有结果。请注意,我们使用的是 Example 类的 of() 工厂方法来创建 Example 实例。

示例2 Query 接口级别

考虑以下 Employee Entity:

@Entity
@Table(name = "employee")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_id", nullable = false)
    private Department department;

    // ... 省略其他字段和方法
}

现在我们想按部门名称以及部门经理姓名搜索 Employee,请使用 QBE 实现此目的。

首先,我们需要创建一个自定义的查询接口,这将包含我们要使用的自定义查询方法。

public interface EmployeeRepositoryCustom {

    List<Employee> findByDepartmentAndManager(String departmentName, String managerName);
}

其次,我们需要创建一个实现,它将包含我们要使用的自定义查询方法的查询方法。

@Repository
public class EmployeeRepositoryCustomImpl implements EmployeeRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Employee> findByDepartmentAndManager(String departmentName, String managerName) {
        Department department = new Department();
        department.setName(departmentName);
        Employee manager = new Employee();
        manager.setName(managerName);
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withIgnorePaths("id")
                .withMatcher("name", match -> match.contains());
        Example<Employee> example = Example.of(manager, matcher);
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
        Root<Employee> root = query.from(Employee.class);
        Join<Employee, Department> join = root.join("department");
        query.select(root)
                .where(criteriaBuilder.equal(join.get("name"), department.getName()),
                        criteriaBuilder.equal(root.get("manager"), manager));
        return entityManager.createQuery(query).getResultList();
    }
}

这将对名为“departmentName”的部门以及名为“managerName”的经理进行搜索。这里我们将经理实例自己创建 Example,以便可以将 Example 用于其名称。我们同时使用 QueryDSL Lambda 表达式和 JPA CriteriaBuilder 构建搜索条件和搜索结果。

最后,我们需要创建 CRUD Repository 接口和实体的 Repository 实现类。

@Transactional(readOnly = true)
public interface EmployeeRepository extends JpaRepository<Employee, Long>, QueryByExampleExecutor<Employee>, EmployeeRepositoryCustom {
}
@Repository
@Transactional(readOnly = true)
public class EmployeeRepositoryImpl extends SimpleJpaRepository<Employee, Long> implements EmployeeRepository {

    public EmployeeRepositoryImpl(EntityManager em) {
        super(Employee.class, em);
    }
}

现在,我们可以在我们的应用程序中调用我们的函数,并且将返回当前按照特定条件过滤的搜索结果集。

List<Employee> employees = employeeRepository.findByDepartmentAndManager("IT", "Mark");

总结

这篇文档介绍了 Spring Data JPA Query By Example Executor 和 ExampleMatcher 接口的细节。QueryByExampleExecutor 提供了按实例的查询语法,并允许您根据已知的实体对象创建查询样例。 ExampleMatcher 用于对如何对示例进行匹配进行描述。最后,我们提供了两个示例,演示如何使用 QBE 筛选出需要的实例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Data JPA系列QueryByExampleExecutor使用详解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java(springboot) 读取txt文本内容代码实例

    下面是关于”Java(springboot) 读取txt文本内容代码实例”的完整攻略: 1. 准备工作 在开始实际操作之前,请确保你已经按照以下步骤准备就绪: 已安装好springboot 已经找到要读取的txt文件,并将其放置于项目的资源文件夹中 2. 代码实现 2.1. 读取文件内容到String import org.springframework.c…

    Java 2023年5月19日
    00
  • spring 和 spring boot 中的属性配置方式

    Spring和Spring Boot中的属性配置方式 Spring和Spring Boot都提供了多种属性配置方式,本文将详细介绍这些方式,并提供两个示例。 Spring中的属性配置方式 Spring中的属性配置方式有以下几种: 1. 使用XML配置文件 使用XML配置文件是Spring最早的属性配置方式。在XML配置文件中,我们可以使用元素来定义Bean,…

    Java 2023年5月15日
    00
  • Java后端Cookie实现(时间戳)代码实例

    请看下面的详细讲解: Java后端Cookie实现(时间戳)代码实例 一、Cookie介绍 Cookie是指服务器通过HTTP响应发送给客户端的一小段文本信息。浏览器会将这些信息存储在客户端,并在下一次访问相同的服务器时发送回服务器。 Cookie可以用于实现在客户端保留数据的功能,比如记住登陆状态、保存浏览历史等。 二、创建Cookie 在Java后端开发…

    Java 2023年6月1日
    00
  • java使用UDP实现点对点通信

    下面是我为您提供的“java使用UDP实现点对点通信”的攻略。 一、什么是UDP UDP是无连接的传输协议,数据报(Datagram)套接字就是基于UDP协议实现的,它不会像TCP那样保证数据传输的可靠性,传输的数据包也不要求应答。但是,UDP具备比TCP更快的传输速度和更小的网络开销,因此,当需要高效传输数据时,可以选择UDP协议。 二、使用UDP实现点对…

    Java 2023年5月20日
    00
  • SpringMVC框架整合Junit进行单元测试(案例详解)

    SpringMVC框架整合Junit进行单元测试(案例详解) 在 SpringMVC 中,我们可以使用 Junit 进行单元测试。本文将详细讲解 SpringMVC 框架整合 Junit 进行单元测试的完整攻略,包括如何配置 SpringMVC、如何使用 Junit 进行单元测试、如何编写测试用例等。 配置 SpringMVC 在使用 Junit 进行单元测…

    Java 2023年5月18日
    00
  • Hibernate使用hbm.xml配置映射关系解析

    Hibernate是Java平台上的一个对象/关系映射框架,常用于在Java应用程序中访问和管理数据库。在Hibernate中,我们需要使用映射文件将Java对象与数据库表进行映射。其中,hbm.xml文件作为Hibernate映射文件的一种形式,是一种XML格式的文件,这个文件用来描述Java对象与数据库表之间的映射关系。本文将详细讲解如何使用hbm.xm…

    Java 2023年5月20日
    00
  • Spring MVC中Ajax实现二级联动的简单实例

    Spring MVC中Ajax实现二级联动的简单实例 在 Spring MVC 中,我们可以使用 Ajax 实现二级联动。本文将详细讲解 Spring MVC 中 Ajax 实现二级联动的完整攻略,并提供两个示例说明。 1. 创建 Spring MVC 控制器 我们需要创建一个 Spring MVC 控制器,用于处理 Ajax 请求。下面是一个简单的示例: …

    Java 2023年5月18日
    00
  • Spring Boot统一异常处理详解

    下面将以“Spring Boot统一异常处理详解”为主题,为大家详细讲解该主题的完整攻略。 一、什么是 Spring Boot 统一异常处理 Spring Boot 统一异常处理指在 Spring Boot 应用程序中,通过设置全局异常处理器,来捕获和处理抛出的异常信息。通过统一异常处理,我们可以将系统中可能出现的各种异常信息进行分类、归纳和统一处理,并返回…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部