这个 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的列连接到其他表(外键)。因此您可以(直接)获取属于 CustomerAddresses,但反之则不行。

更新(希望我有更多 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 表中可以看出,id12 的记录都属于具有 的同一客户>cust_id101

【讨论】:

以上是关于这个 JPA 映射究竟是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

这个 Promise 示例究竟是如何工作的?

在这个 Angular 2 示例中,这种 Observable 行为究竟是如何工作的?

这个“包含”其他一些属性文件的属性文件究竟是如何工作的?

这个简单的 PrimeNG Angular 2 示例究竟是如何工作的?

关于 Angular 2 中的事件发出的一些疑问。这个例子究竟是如何工作的?

这个在 Spring 中处理 POST 请求的 REST 方法究竟是如何工作的?