在Spring Data中按嵌套对象的属性查找

2025/03/23

1. 概述

在Spring Data中,通常使用基于方法名称的派生查询来查询实体。在处理实体之间的关系(例如嵌套对象)时,Spring Data提供了各种机制来从这些嵌套对象中检索数据。

在本教程中,我们将探讨如何使用查询派生和JPQL(Java持久化查询语言)通过嵌套对象的属性进行查询。

2. 场景概述

让我们考虑一个有两个实体的简单场景:Customer和Order每个Order通过ManyToOne关系链接到Customer。

我们希望找到属于具有特定email的客户的所有订单。在这种情况下,email是Customer实体的属性,而我们的主要查询将在Order实体上执行。

以下是我们的示例实体:

@Entity
@Table(name = "customers")
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String email;

    // getters and setters
}

@Entity
@Table(name = "orders")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Date orderDate;

    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer customer;

    // getters and setters
}

3. 使用查询派生

Spring Data JPA通过允许开发人员从Repository接口中的方法签名派生查询来简化查询创建

3.1 正常用例

在正常情况下,如果我们想通过关联的Customer的email查找Order实体,我们可以简单地这样做:

public interface OrderRepository extends JpaRepository<Order, Long> {
    List<Order> findByCustomerEmail(String email);
}

生成的SQL将如下所示:

select
    o.id,
    o.customer_id,
    o.order_date
from
    orders o
left outer join
    customers c
        on o.customer_id = c.id
where
    c.email = ?

3.2 关键字大小写冲突

现在,假设除了嵌套的Customer对象之外,Order类本身还有一个名为customerEmail的字段。在这种情况下,Spring Data JPA不会像我们预期的那样仅在customers表上生成查询:

select
    o.id,
    o.customer_id,
    o.customer_email,
    o.order_date
from
    orders o
where
    o.customer_email = ?

在这种情况下,我们可以使用下划线字符来定义JPA应该尝试拆分关键字的位置

List<Order> findByCustomer_Email(String email);

这里,下划线帮助Spring Data JPA正确解析查询方法。

4. 使用JPQL查询

如果我们想要更好地控制查询逻辑或执行更复杂的操作,JPQL是一个不错的选择。要使用JPQL查询按Customer的email查询Order,我们可以编写如下代码:

@Query("SELECT o FROM Order o WHERE o.customer.email = ?1")
List<Order> findByCustomerEmailAndJPQL(String email);

这使我们可以灵活地编写更具定制性的查询,而不依赖于方法名称约定。

5. 总结

在本文中,我们探讨了如何通过Spring Data中嵌套对象的属性查询数据。我们介绍了查询派生和自定义JPQL查询,通过利用这些技术,我们可以轻松处理许多用例。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章