Java JPQL查询,用于从一对一关系中选择实体,其中该实体的相对关系有一个匹配特定条件的字段
我有三个实体:EntityA映射到表a,EntityB映射到表b,以及目录映射到目录。在数据库中,在表b和目录b、目录b和外部参照之间有一个多对多表。EntityB有一个字段:Long aId和一个字段:List catalogs。目录实体有一个字段:字符串名称。给定EntityB的ID列表和表示目录名称的字符串,我需要检索EntityA的所有实例,其ID与EntityB的aId的ID匹配,并且给定的目录名称与EntityB的一个目录的ID匹配 我已经通过常规SQL成功地获取了正确的数据,但是我正在努力用JPQL重新创建查询。下面是SQL查询: SQL: 爪哇:Java JPQL查询,用于从一对一关系中选择实体,其中该实体的相对关系有一个匹配特定条件的字段,java,sql,hibernate,plsql,jpql,Java,Sql,Hibernate,Plsql,Jpql,我有三个实体:EntityA映射到表a,EntityB映射到表b,以及目录映射到目录。在数据库中,在表b和目录b、目录b和外部参照之间有一个多对多表。EntityB有一个字段:Long aId和一个字段:List catalogs。目录实体有一个字段:字符串名称。给定EntityB的ID列表和表示目录名称的字符串,我需要检索EntityA的所有实例,其ID与EntityB的aId的ID匹配,并且给定的目录名称与EntityB的一个目录的ID匹配 我已经通过常规SQL成功地获取了正确的数据,但是我
是的,你可以用
TypedQuery<TableA> q = entityManager.createQuery
("Select a from TableA a where a.aId in(Select b.aId from TableB b " +
"join b.catalogs c where c.name=:name)", TableA.class);
q.setParameter("name", "some2");
那么JPQL将看起来像:
TypedQuery<TableA> q = entityManager.createQuery
("Select distinct b.tableA from TableB b join b.catalogs c " +
"where c.name=:name", TableA.class);
q.setParameter("name", "some2");
注意关键字distinct,它会删除结果列表中的所有重复项
不要使用FetchType.EAGER,除非绝对必要,否则请使用FetchType.LAZY。到目前为止,您尝试了什么?我想我已经找到了答案。到目前为止,我所拥有的是:从EntityA中选择a作为a,其中a.aId在SELECT中选择b.aId从EntityB中选择b作为b左连接b.catalogs作为bCatalog与bCatalog.name=:catalogName我完全同意这两个实体之间应该有明确的关系,但这是一个庞大代码库中的核心实体,我只能想象如果我改变它,会有多大的破坏。有空的时候,我可能会重构它。
@Entity
@Table(name = "table_b")
public class EntityA {
@Id
@Column(name = "table_b_id")
private Long bId;
@Column(name = "table_a_id")
private Long aId;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH})
@JoinTable(name = "b_catalog_xref",
joinColumns = {@JoinColumn(name = "table_b_id")},
inverseJoinColumns = {@JoinColumn(name = "catalog_id")})
@Fetch(FetchMode.SELECT)
@OrderBy("name ASC")
List<Catalog> catalogs
...
}
@Entity
@Table(name = "catalog")
public class Catalog {
@Id
@Column(name = "catalog_id")
private Long catalogId;
@Column(name = "catalog_name")
private String name;
...
}
TypedQuery<TableA> q = entityManager.createQuery
("Select a from TableA a where a.aId in(Select b.aId from TableB b " +
"join b.catalogs c where c.name=:name)", TableA.class);
q.setParameter("name", "some2");
@Entity
@Table(name = "table_b")
public class EntityB {
...
// @Column(name = "table_a_id")
// private Long aId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "table_a_id")
private TableA tableA;
...
}
TypedQuery<TableA> q = entityManager.createQuery
("Select distinct b.tableA from TableB b join b.catalogs c " +
"where c.name=:name", TableA.class);
q.setParameter("name", "some2");