【问题标题】:How to write an SQL SELECT in JPA with 3 JOINs?如何在 JPA 中使用 3 个 JOIN 编写 SQL SELECT?
【发布时间】:2013-10-30 23:53:39
【问题描述】:

我有实体:

@Entity(name = "sent_message")
public class SentMessage extends AbstractEntity {
    @ManyToOne(fetch = FetchType.LAZY)
    private TargetGroup targetGroup;
    @ManyToOne(fetch = FetchType.LAZY)
    private Customer customer;
    @ManyToOne(fetch = FetchType.LAZY)
    private MessageTemplate template;
    private Date sentDate;
    getter.setter...
}

@Entity(name = "target_group")
public class TargetGroup extends AbstractEntity {
    private String name;
    private String description;
    @ManyToMany(fetch = FetchType.LAZY)
    private List<Customer> customers = new ArrayList<>();
    getter.setter...
}

@Entity(name = "customer")
public class Customer extends AbstractEntity {
    private String name;
    private String email;
    private String mobile;
    @ManyToMany(mappedBy="customers", fetch = FetchType.LAZY)
    private List<TargetGroup> targetGroups = new ArrayList<>();
    @OneToMany(mappedBy = "customer", fetch = FetchType.LAZY)
    private List<SentMessage> sentMessages = new ArrayList<>();
    getter.setter...
}

@Entity(name = "message_template")
public class MessageTemplate extends AbstractEntity {
    private String subject;
    private String text;
    @OneToMany(mappedBy = "template", fetch = FetchType.LAZY)
    private List<SentMessage> sentMessages;
    getter.setter...
}

我希望 TargetGroup、Customer、MessageTemplate 成为查询的结果。我的选择:

SELECT msg FROM SentMessage msg JOIN msg.targetGroup tg, msg.customer cust, msg.template temp WHERE ....

这是正确的,或者我应该怎么写?我想要所有实体的所有参数。 谢谢!

编辑:我想按TargetGroup的名字,Customer的名字等搜索,WHERE怎么写??

【问题讨论】:

    标签: sql jpa ejb entity jpql


    【解决方案1】:

    您必须在查询的select 子句中列出您想要的结果:

    SELECT msg.targetGroup, msg.customer, msg.template FROM SentMessage msg 
    

    您将获得一个包含数据的Object[]

    如果由于延迟提取而遇到问题,可以添加 fetch join 来检索相关实体:

    SELECT msg.targetGroup, msg.customer, msg.template FROM SentMessage msg join fetch msg.targetGroup tg join fetch  msg.customer cust join fetch msg.template temp
    

    编辑您的评论表明您还需要在结果中包含“父”消息。在这种情况下,创建投影查询(列出 select 子句中的所有属性)是没有意义的。只需获取父消息并调用常规 getter 以访问 CustomerTargetGroup 和其他关联。如果出现延迟提取问题,请使用提取连接。

    SELECT msg FROM SentMessage msg 
    

    SELECT msg FROM SentMessage msg join fetch msg.targetGroup tg join fetch  msg.customer cust join fetch msg.template temp
    

    编辑 2 要为查询添加约束,您可以添加引用任何 id 变量的常规 where 子句:

    ... join fetch  msg.customer cust where cust.name = :cust_name... 
    

    然而 fetch join 和 where 子句的行为有点出乎意料 - fetch 也受到 where 子句的限制。参考this thread

    【讨论】:

    • 我列出了 3 个结果(msg.targetGroup、msg.customer、msg.template),我也会从 SentMessage 表中获取参数吗?或者我应该这样写:SELECT msg, msg.targetGroup, msg.customer, msg.template FROM SentMessage msg
    • 如果我想检查 Customer 表中的参数,如何在 WHERE 位置进行搜索?可能我想搜索客户的名字,WHERE应该怎么写?
    • @victorio 希望我理解正确。请查看更新后的答案。
    • @victorio - 请不要只是在 cmets 中堆积后续问题。检查您的原始请求是否已解决并返回一些反馈。解决最初的问题后,请打开一个新线程以了解更多问题。
    • 几乎!但是如果我想在 WHERE 中搜索客户的名字,然后在 WHERE 中搜索 TargetGroup 的名字呢??
    猜你喜欢
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2022-08-15
    • 2011-09-04
    • 2011-08-06
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    相关资源
    最近更新 更多