这个 JPA 映射究竟是如何工作的?
Posted
技术标签:
【中文标题】这个 JPA 映射究竟是如何工作的?【英文标题】:How exactly works this JPA mapping? 【发布时间】:2015-01-10 16:26:25 【问题描述】:我正在学习 Spring Core 认证,但我对课程幻灯片上的这个 JPA 示例有一些疑问:
有 2 个实体类映射 2 个表:
1) 映射 T_CUSTOMER 数据库表的 Customer 实体类:
@Entity
@Table(name= “T_CUSTOMER”)
public class Customer
@Id
@Column (name=“cust_id”)
private Long id;
@OneToMany
@JoinColumn (name=“cid”)
private Set<Address> addresses;
…
…
…
2) Address 映射T_ADDRESS DB 表的实体类:
@Entity
@Table(name= “T_ADDRESS”)
public class Address
@Id private Long id;
private String street;
private String suburb;
private String city;
private String postcode;
private String country;
所以我对这个提供的例子有两个疑问:
1) 为什么进入Address类没有@Column注解?如果 @Column 注释没有提供,JPA 可能会使用属性名称与数据库表列名称进行默认匹配?
2) 正如您在前面的示例中看到的那样,Customer 实体类包含表示 一对多 关系的字段
@OneToMany
@JoinColumn (name=“cid”)
private Set<Address> addresses;
所以我认为这意味着 T_CUSTOMER 表的一行与 T_ADDRESS 表的更多行相关联,并且这些行表示为 T_ADDRESS 表的集合strong>地址模型实例。对吗?
现在我怀疑加入是使用 cid 名称完成的。此名称不显示为我的 Address 类的属性。那是什么?它是属于 T_ADDRESS 的列的名称,并且没有被实体类 Address 映射吗?
Tnx
【问题讨论】:
【参考方案1】:1:你的假设是正确的
2:这是一个uni-directional one-to-many relation,这意味着每个客户都可以拥有一个地址列表,并通过名为cid的列连接到其他表(外键)。因此您可以(直接)获取属于 Customer 的 Addresses,但反之则不行。
更新(希望我有更多 SO 评论)
currently accepted answer 的某些部分不正确:
如果您没有使用 @Column 注释 Bean/Entity 类的字段/属性,则 ORM 提供程序(例如 Hibernate)将为相应的 Bean/Entity 创建一个表,其中列名作为您的 Bean/Entity 字段名。
JPA implementations such as Hibernate 需要一些额外的配置来自动为您生成/更新表。对于 Hibernate,您需要在持久性配置中设置 hbm2ddl.auto
属性。
您的 Customer 类包含一对一的映射
显然它包含一个一对多的映射。
【讨论】:
嗯,当您说我必须在两个表中都有 cid 列时,我不明白您的意思。我认为我需要将 cid 列放入 T_ADDRESS 类中,并且该列必须包含 T_CUSTOMER 行的主键的值(作为外键)。还是不行? @AndreaNobili 是的,我就是这个意思。 感谢您指出 hbm2ddl.auto 点,我忘了在我的帖子中提及它。为此 +1【参考方案2】:1) 为什么进入Address类没有@Column注解?
@Column 注释是可选的。默认情况下,如果您没有使用 @Column 注释 Bean/Entity 类的字段/属性,则 ORM 提供程序(例如 Hibernate)将为对应的 Bean/Entity 创建一个表,列名作为您的 Bean/Entity 字段名。
2) 现在我怀疑连接是使用 cid 名称完成的。此名称不显示为我的地址类的属性。那是什么?是属于 T_ADDRESS 且未被实体类 Address 映射的列名吗?
您的 Customer 类包含一个一对一的映射:
...
@OneToMany
@JoinColumn (name=“cid”)
private Set<Address> addresses;
…
使用此映射,ORM 可以识别地址表中的哪些记录属于具有特定 ID 的客户;
考虑这个客户表:
----------------------------------------------------------------------------
| Cust_id | Cust_firstname | Cust_lastname | Cust_email | Cust_mobile |
----------------------------------------------------------------------------
| 101 | XXXX | YYYYY |xxx@xyz.com | 8282263131 |
----------------------------------------------------------------------------
上述客户表有一条 cust_id 为 101 的记录。
现在考虑这个地址表:
----------------------------------------------------------------------------
| id | street | suburb | city | zipcode | cid |
----------------------------------------------------------------------------
| 1 | streetX | AreaY | cityZ | 54726 | 101 |
----------------------------------------------------------------------------
| 2 | streetXA | AreaYB | cityZS | 60660 | 101 |
----------------------------------------------------------------------------
您的地址表包含一个 外键 列作为 cid,这是在您的辅助表中包含外键列的好习惯,这是默认机制在休眠中。
从 Address 表中可以看出,id 为 1 和 2 的记录都属于具有 的同一客户>cust_id 为 101
【讨论】:
以上是关于这个 JPA 映射究竟是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
在这个 Angular 2 示例中,这种 Observable 行为究竟是如何工作的?
这个简单的 PrimeNG Angular 2 示例究竟是如何工作的?