1. 概述

在这个教程中,我们将学习Java持久化API(JPA)中@JoinColumn@PrimaryKeyJoinColumn的区别。JPA允许应用程序访问关系型数据库中的数据,它定义了数据在数据库中的存储方式以及应用程序如何访问这些数据。

Java对象通过JPA注解映射到数据库表。虽然有许多JPA注解,但我们将主要关注@JoinColumn@PrimaryKeyJoinColumn

2. @JoinColumn注解

@JoinColumn注解定义了连接两个实体的列。它定义了一个实体的外键列及其关联的主键字段

这个注解允许我们在实体之间建立关系,快速地保存和访问数据。通常,它与@ManyToOne@OneToOne注解一起使用来定义关联。

下面的示例展示了如何使用@JoinColumn注解:

@Entity
public class Email {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String address;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employee_id", referencedColumnName = "id")
    private OfficialEmployee employee;
   
    //getters and setters
}
@Entity
public class OfficialEmployee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "employee")
    private List<Email> emails;

    //getters and setters
}

3. @PrimaryKeyJoinColumn注解

@PrimaryKeyJoinColumn注解指定一个实体的主键是另一个实体的外键。它通过使实体表的主键列成为关联实体的外键来映射两个实体之间的关系

下面的示例展示了如何使用@PrimaryKeyJoinColumn注解:

@Entity
@Table(name = "person")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToOne
    @PrimaryKeyJoinColumn
    private Department department;

    // getters and setters
}

@Entity
@Table(name = "department")
public class Department {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // getters and setters
}

在这个例子中,我们有两个实体:PersonDepartmentPerson实体有一个名为Department的字段,它使用@OneToOne@PrimaryKeyJoinColumn引用Department实体。

Department表的主键将是Person表的外键。Department实体有一个@Id字段,作为Department表的主键。

4. @JoinColumn@PrimaryKeyJoinColumn的区别

@JoinColumn@PrimaryKeyJoinColumn之间的主要区别在于它们处理实体间关系的方式。

@JoinColumn指的是一个表中的列,它包含对另一个表的外键。当一个表中的外键引用另一个表的主键时,我们会使用这个注解

相反,@PrimaryKeyJoinColumn表示应该通过对应于关联实体主键的外键列来映射关联。简而言之,@JoinColumn映射常规的外键关联,而@PrimaryKeyJoinColumn映射关联,其中关联实体的主键也被用作当前实体的外键。

重要的是要注意,@PrimaryKeyJoinColumn通常用于一对一关联,而@JoinColumn可用于一对一、一对多、多对一和多对多关联。

5. 何时使用@JoinColumn@PrimaryKeyJoinColumn

我们如何建模关系取决于具体的情况。为了明确地指定外键列的映射,我们可以使用@JoinColumn,特别是当它不是目标实体的主键时。

当外键列是目标实体的主键时,我们可以使用@PrimaryKeyJoinColumn。如果没有指定注解,JPA将使用依赖于实体和属性名称的映射策略。

6. 总结

在这篇文章中,我们探讨了@JoinColumn@PrimaryKeyJoinColumn的区别。它们在一对一或多对一的关系中连接两个实体。

如往常一样,所有源代码可在GitHub上查看:https://github.com/eugenp/tutorials/tree/master/persistence-modules/hibernate-annotations