【问题标题】:How exactly works this JPA mapping?这个 JPA 映射究竟是如何工作的?
【发布时间】: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

【问题讨论】:

    标签: java spring hibernate jpa jpa-2.0


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2018-03-03
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 2011-06-26
      相关资源
      最近更新 更多