Hibernate JPQL HQL查询操作在类层次结构之上,采用连接继承策略并应用DTO投影
假设我有以下具有联合继承策略的类层次结构:Hibernate JPQL HQL查询操作在类层次结构之上,采用连接继承策略并应用DTO投影,hibernate,jpa,hql,jpa-2.0,jpql,Hibernate,Jpa,Hql,Jpa 2.0,Jpql,假设我有以下具有联合继承策略的类层次结构: @Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class Notification { protected Long id; protected Long code; protected Notification() { } } @Entity @PrimaryKeyJoinColumn(name = "NO
@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查询,该查询将返回List
,其中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 results=em.createQuery(
“选择新建com.your.entities.NotificationDetails(”
+合并(s.phoneNumber,p.application)
+合并(s.smsText,p.pushText)
+“)来自通知n”
+“在s.id=n.id上左加入Sms s”
+“p.id=n.id上的左连接推送p”,
NotificationDetails.class).getResultList();
它可以工作,但生成的sql效率很低:
选择
合并(sms1.sms\u手机、push2.push\u应用程序)为col\u 0\u 0,
合并(sms1\uU.sms\u文本,push2\uU.push\u文本)为列1\u 0\u
从TEST_SCHEMA.TST_通知通知0_
左外连接(
测试\u SCHEMA.TST\u SMS sms1\u
内部连接测试\u SCHEMA.TST\u通知sms1\u 1_
在sms1_u.sms_not_id=sms1_1_u.not_id上
)打开(sms1_u.sms_not_id=notification0_u.not_id)
左外连接(
测试\u SCHEMA.TST\u推送2\u
内部连接测试\u SCHEMA.TST\u通知push2\u 1\u
在push2上。PUSHU not\U id=push2\U 1\U not\U id
)on(push2\u.PUSHU not\u id=通知0\u.not\u id)
如果性能在这里很重要,我想最好使用本机查询并将其(例如通过
@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();
List results=em.createQuery(
“从通知n中选择新的com.your.entities.NotificationDetails(coalesce(n.phoneNumber,n.application)、coalesce(n.smsText,n.pushText))”,
NotificationDetails.class
).getResultList();
您测试过吗?实体Notification
没有phoneNumber、application、smsText、pushText属性,并且没有显式转换到Sms
或Push
它们不可用。我过去已经多次这样做了,所以是的,这是有效的。