JPA 映射:一个 table 的主键列到另一个 table 的非 Pk/Fk 列
JPA mapping :Primary key column of one table to non Pk/Fk column of another table
@Entity
@Table(name = "TableA")
public class TableAEntity{
@Id
@Column(name = "RUL_ID"
private Integer rulId;
@Column(name = "COMMENT"
private Integer comment;
@OneToOne
@JoinColumn(name = "RUL_ID" referencedColumnName ="PRNT_ID", insertable=false, updatable=false)
private TableBEntity tableB;
//GETTERS AND SETTERS
}
@Entity
@Table(name = "TableB")
public class TableBEntity{
@Id
@Column(name = "ADD_ID"
private Integer addID;
@Column(name = "PRNT_ID"
private Integer prntId;
//GETTERS AND SETTERS
}
有 2 个数据库表。
- 主键为 rulId 的表 A。
- 主键为 addID 的表 B。
我必须使用 JPA 本机查询来实现自定义的 JOIN 查询。
Java代码为:
StringBuilder querySql = "select a.rulId, b.prntId from TableA a JOIN TableB b ON a.rulID = b.prntId"
Query tabQuery = entityManager.createNativeQuery(querySql.toString, TableAEntity.class)
List<TableAEntity> entityList = tabQuery.getResultList();
如何建立一对一(TableA:TableB)关系,当它们没有任何键链接时(pk/fk)。
我无法将 ResultList 映射到我的实体 class.Primary TableA“rulId”的键总是链接到 TableB“addId”的主键,其中我想将它关联到“prntId”。
谁能帮忙解决这个问题。
有几点需要注意:
- 对于 JPA 查询,您必须使用
createQuery
(createNativeQuery
用于 SQL 查询);
@Table(name=...)
将在数据库中定义 table 的名称,但在编写 JPQL 查询时不会。为此,您可以使用 @Entity(name="...")
。在你的情况下,它应该是 @Entity(name="TableA")
;
- 查询的return值是两个字段,不是
TableAEntity
。所以将它作为参数传递给 createQuery
是错误的;
- return
a.id
和 b.id
很奇怪。如果你想要实体,你可以 return a
和 b
.
如果TableA
和TableB
之间存在关联,例如:
@Entity(name = "TableA")
public class TableAEntity {
...
@OneToOne
@JoinColumn(referencedColumnName ="PRNT_ID", insertable=false, updatable=false)
public TableBEntity tableB;
}
那么你可以运行下面的查询:
String jpqlQuery = "from TableA a join fetch a.tableB b";
List<TableAEntity> entityList = entityManager.createQuery(jpqlQuery, TableAEntity.class).getResultList()
entityList.foreach( tableAEntity -> {
TableBEntity tabB = tableAEntity.tableB;
});
如果TableA
和TableB
之间没有关联:
String jpqlQuery = "select a, b from TableA a JOIN TableB b ON a.rulID = b.prntId";
List<Object[]> entityList = entityManager.createQuery(jpqlQuery).getResultList()
entityList.foreach( row -> {
TableAEntity tabA = (TableAEntity) row[0];
TableBEntity tabB = (TableBEntity) row[1];
});
但如果您真的只需要 ID,这也行得通:
String jpqlQuery = "select a.rulId, b.prntId from TableA a JOIN TableB b ON a.rulID = b.prntId";
List<Object[]> entityList = entityManager.createQuery(jpqlQuery).getResultList()
entityList.foreach( row -> {
Integer tabAId = (Integer) row[0];
Integer tabBId = (Integer) row[1];
...
});
请注意,您可以更改 select 并混合使用这两种方法。
但是因为 TableAEntity
和 TableBEntity
之间存在关联,您可以将所有这些重写为:
String jpqlQuery = "from TableA";
List<TableAEntity> entityList = entityManager.createQuery(jpqlQuery,
TableAEntity.class).getResultList()
entityList.foreach( entity -> {
TableAEntity tabA = entity;
TableBEntity tabB = entity.getTableB();
...
});
无论有无关联,您都可以从 select 子句中 return 获得您需要的所有值组合:
select a, b.addID from ...
select a, b from ...
@Entity
@Table(name = "TableA")
public class TableAEntity{
@Id
@Column(name = "RUL_ID"
private Integer rulId;
@Column(name = "COMMENT"
private Integer comment;
@OneToOne
@JoinColumn(name = "RUL_ID" referencedColumnName ="PRNT_ID", insertable=false, updatable=false)
private TableBEntity tableB;
//GETTERS AND SETTERS
}
@Entity
@Table(name = "TableB")
public class TableBEntity{
@Id
@Column(name = "ADD_ID"
private Integer addID;
@Column(name = "PRNT_ID"
private Integer prntId;
//GETTERS AND SETTERS
}
有 2 个数据库表。
- 主键为 rulId 的表 A。
- 主键为 addID 的表 B。
我必须使用 JPA 本机查询来实现自定义的 JOIN 查询。
Java代码为:
StringBuilder querySql = "select a.rulId, b.prntId from TableA a JOIN TableB b ON a.rulID = b.prntId"
Query tabQuery = entityManager.createNativeQuery(querySql.toString, TableAEntity.class)
List<TableAEntity> entityList = tabQuery.getResultList();
如何建立一对一(TableA:TableB)关系,当它们没有任何键链接时(pk/fk)。 我无法将 ResultList 映射到我的实体 class.Primary TableA“rulId”的键总是链接到 TableB“addId”的主键,其中我想将它关联到“prntId”。
谁能帮忙解决这个问题。
有几点需要注意:
- 对于 JPA 查询,您必须使用
createQuery
(createNativeQuery
用于 SQL 查询); @Table(name=...)
将在数据库中定义 table 的名称,但在编写 JPQL 查询时不会。为此,您可以使用@Entity(name="...")
。在你的情况下,它应该是@Entity(name="TableA")
;- 查询的return值是两个字段,不是
TableAEntity
。所以将它作为参数传递给createQuery
是错误的; - return
a.id
和b.id
很奇怪。如果你想要实体,你可以 returna
和b
.
如果TableA
和TableB
之间存在关联,例如:
@Entity(name = "TableA")
public class TableAEntity {
...
@OneToOne
@JoinColumn(referencedColumnName ="PRNT_ID", insertable=false, updatable=false)
public TableBEntity tableB;
}
那么你可以运行下面的查询:
String jpqlQuery = "from TableA a join fetch a.tableB b";
List<TableAEntity> entityList = entityManager.createQuery(jpqlQuery, TableAEntity.class).getResultList()
entityList.foreach( tableAEntity -> {
TableBEntity tabB = tableAEntity.tableB;
});
如果TableA
和TableB
之间没有关联:
String jpqlQuery = "select a, b from TableA a JOIN TableB b ON a.rulID = b.prntId";
List<Object[]> entityList = entityManager.createQuery(jpqlQuery).getResultList()
entityList.foreach( row -> {
TableAEntity tabA = (TableAEntity) row[0];
TableBEntity tabB = (TableBEntity) row[1];
});
但如果您真的只需要 ID,这也行得通:
String jpqlQuery = "select a.rulId, b.prntId from TableA a JOIN TableB b ON a.rulID = b.prntId";
List<Object[]> entityList = entityManager.createQuery(jpqlQuery).getResultList()
entityList.foreach( row -> {
Integer tabAId = (Integer) row[0];
Integer tabBId = (Integer) row[1];
...
});
请注意,您可以更改 select 并混合使用这两种方法。
但是因为 TableAEntity
和 TableBEntity
之间存在关联,您可以将所有这些重写为:
String jpqlQuery = "from TableA";
List<TableAEntity> entityList = entityManager.createQuery(jpqlQuery,
TableAEntity.class).getResultList()
entityList.foreach( entity -> {
TableAEntity tabA = entity;
TableBEntity tabB = entity.getTableB();
...
});
无论有无关联,您都可以从 select 子句中 return 获得您需要的所有值组合:
select a, b.addID from ...
select a, b from ...