使用内部联接时映射 NativeQuery 结果
Mapping NativeQuery results when using inner join
我有以下情况:
@Entity
@XmlRootElement
@Table(name = "TB_A")
public class A implements Serializable {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CD_B")
private B b;
}
@Entity
@XmlRootElement
@Table(name = "TB_B")
public class B implements Serializable {
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "CD_B")
@JsonIgnore
private Set<C> c = new HashSet<>();
}
@Entity
@XmlRootElement
@Table(name = "TB_C")
public class C implements Serializable {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CD_B")
private B b;
}
我需要运行以下代码:
String sql = "SELECT * FROM TB_A a "
+ "INNER JOIN TB_B b ON ... "
+ "LEFT JOIN TB_C c ON ... ";
Query query = em.createNativeQuery(sql, A.class);
List<A> AList = query.getResultList();
for(A a : AList) {
List<c> CList = a.getB().getC();
}
分析执行的查询,我注意到每次我访问元素 B 和 C 时,JPS 运行宁一个 SELECT。
如何正确映射此 nativeQuery 以使用 lazyLoad?
- Obs:我必须使用 NativeQuery,因为在我的 WHERE 子句中我需要使用来自 Oracle 的特定函数。所以 JPQL 对我来说不是一个选择(如果我能使用它,我的生活会容易得多!)。
简答:你不能。
这一行的作用:
Query query = em.createNativeQuery(sql, A.class);
是执行你的SQL,然后扔掉任何与A.class无关的东西。
然后你的 for 循环:
for(A a : AList) {
List<c> CList = a.getB().getC();
}
再次获取所有内容。
在这里您再次使用 JPA,它对您之前执行的查询一无所知。
在某些情况下,您可以尝试映射到 C.class
。
然后你就可以完全避免循环。
如果在您的情况下您需要 A.class 和 C.class,您可以改为查看 ResultSetMapping:http://www.java2s.com/Tutorial/Java/0355__JPA/SqlResultSetMappingForHierarchicalEntity.htm
我有以下情况:
@Entity
@XmlRootElement
@Table(name = "TB_A")
public class A implements Serializable {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CD_B")
private B b;
}
@Entity
@XmlRootElement
@Table(name = "TB_B")
public class B implements Serializable {
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "CD_B")
@JsonIgnore
private Set<C> c = new HashSet<>();
}
@Entity
@XmlRootElement
@Table(name = "TB_C")
public class C implements Serializable {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CD_B")
private B b;
}
我需要运行以下代码:
String sql = "SELECT * FROM TB_A a "
+ "INNER JOIN TB_B b ON ... "
+ "LEFT JOIN TB_C c ON ... ";
Query query = em.createNativeQuery(sql, A.class);
List<A> AList = query.getResultList();
for(A a : AList) {
List<c> CList = a.getB().getC();
}
分析执行的查询,我注意到每次我访问元素 B 和 C 时,JPS 运行宁一个 SELECT。
如何正确映射此 nativeQuery 以使用 lazyLoad?
- Obs:我必须使用 NativeQuery,因为在我的 WHERE 子句中我需要使用来自 Oracle 的特定函数。所以 JPQL 对我来说不是一个选择(如果我能使用它,我的生活会容易得多!)。
简答:你不能。
这一行的作用:
Query query = em.createNativeQuery(sql, A.class);
是执行你的SQL,然后扔掉任何与A.class无关的东西。
然后你的 for 循环:
for(A a : AList) {
List<c> CList = a.getB().getC();
}
再次获取所有内容。
在这里您再次使用 JPA,它对您之前执行的查询一无所知。
在某些情况下,您可以尝试映射到 C.class
。
然后你就可以完全避免循环。
如果在您的情况下您需要 A.class 和 C.class,您可以改为查看 ResultSetMapping:http://www.java2s.com/Tutorial/Java/0355__JPA/SqlResultSetMappingForHierarchicalEntity.htm