JPQL HQL 查询在 class 层次结构之上运行,具有联合继承策略并应用 DTO 投影
JPQL HQL query operating on top of class hierarchy with joined inheritance strategy and applying DTO projection
假设我有以下 class 继承策略的层次结构:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Notification {
protected Long id;
protected Long code;
protected Notification() {
}
}
@Entity
@PrimaryKeyJoinColumn(name = "NOTIFICATION_ID")
public class Sms extends Notification {
private String phoneNumber;
private String smsText;
public Sms() {
}
}
@Entity
@PrimaryKeyJoinColumn(name = "NOTIFICATION_ID")
public class Push extends Notification {
private String application;
private String pushText;
public Push() {
}
}
我如何编写 JPQL / HQL 查询将 return List<NotificationDetails>
其中 NotificationDetails
是:
public class NotificationDetails {
private final String contact;
private final String content;
public NotificationDetails(String contact, String content) {
this.contact = contact;
this.content = content;
}
}
其中映射应如下所示:
contact - phoneNumber / application
content - smsText / pushText
你可以尝试使用下面的jpql:
List<NotificationDetails> results = em.createQuery(
"select new com.your.entities.NotificationDetails( "
+ " coalesce(s.phoneNumber, p.application), "
+ " coalesce(s.smsText, p.pushText) "
+ ") from Notification n "
+ "left join Sms s on s.id = n.id "
+ "left join Push p on p.id = n.id ",
NotificationDetails.class).getResultList();
有效,但生成效率很低sql:
select
coalesce(sms1_.sms_phone, push2_.push_app) as col_0_0_,
coalesce(sms1_.sms_text, push2_.push_text) as col_1_0_
from TEST_SCHEMA.TST_NOTIFICATION notificati0_
left outer join (
TEST_SCHEMA.TST_SMS sms1_
inner join TEST_SCHEMA.TST_NOTIFICATION sms1_1_
on sms1_.sms_not_id=sms1_1_.not_id
) on (sms1_.sms_not_id=notificati0_.not_id)
left outer join (
TEST_SCHEMA.TST_PUSH push2_
inner join TEST_SCHEMA.TST_NOTIFICATION push2_1_
on push2_.push_not_id=push2_1_.not_id
) on (push2_.push_not_id=notificati0_.not_id)
如果性能在这里很重要,我想最好使用本机查询并将其映射(对于 example 通过 @SqlResultSetMapping
)到 NotificationDetails
dto。
Hibernate 支持隐式子类型 属性 解析,因此您可以使用如下查询:
List<NotificationDetails> results = em.createQuery(
"select new com.your.entities.NotificationDetails(coalesce(n.phoneNumber, n.application), coalesce(n.smsText, n.pushText)) from Notification n ",
NotificationDetails.class
).getResultList();
假设我有以下 class 继承策略的层次结构:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Notification {
protected Long id;
protected Long code;
protected Notification() {
}
}
@Entity
@PrimaryKeyJoinColumn(name = "NOTIFICATION_ID")
public class Sms extends Notification {
private String phoneNumber;
private String smsText;
public Sms() {
}
}
@Entity
@PrimaryKeyJoinColumn(name = "NOTIFICATION_ID")
public class Push extends Notification {
private String application;
private String pushText;
public Push() {
}
}
我如何编写 JPQL / HQL 查询将 return List<NotificationDetails>
其中 NotificationDetails
是:
public class NotificationDetails {
private final String contact;
private final String content;
public NotificationDetails(String contact, String content) {
this.contact = contact;
this.content = content;
}
}
其中映射应如下所示:
contact - phoneNumber / application
content - smsText / pushText
你可以尝试使用下面的jpql:
List<NotificationDetails> results = em.createQuery(
"select new com.your.entities.NotificationDetails( "
+ " coalesce(s.phoneNumber, p.application), "
+ " coalesce(s.smsText, p.pushText) "
+ ") from Notification n "
+ "left join Sms s on s.id = n.id "
+ "left join Push p on p.id = n.id ",
NotificationDetails.class).getResultList();
有效,但生成效率很低sql:
select
coalesce(sms1_.sms_phone, push2_.push_app) as col_0_0_,
coalesce(sms1_.sms_text, push2_.push_text) as col_1_0_
from TEST_SCHEMA.TST_NOTIFICATION notificati0_
left outer join (
TEST_SCHEMA.TST_SMS sms1_
inner join TEST_SCHEMA.TST_NOTIFICATION sms1_1_
on sms1_.sms_not_id=sms1_1_.not_id
) on (sms1_.sms_not_id=notificati0_.not_id)
left outer join (
TEST_SCHEMA.TST_PUSH push2_
inner join TEST_SCHEMA.TST_NOTIFICATION push2_1_
on push2_.push_not_id=push2_1_.not_id
) on (push2_.push_not_id=notificati0_.not_id)
如果性能在这里很重要,我想最好使用本机查询并将其映射(对于 example 通过 @SqlResultSetMapping
)到 NotificationDetails
dto。
Hibernate 支持隐式子类型 属性 解析,因此您可以使用如下查询:
List<NotificationDetails> results = em.createQuery(
"select new com.your.entities.NotificationDetails(coalesce(n.phoneNumber, n.application), coalesce(n.smsText, n.pushText)) from Notification n ",
NotificationDetails.class
).getResultList();