Hiberate 一对一映射注解示例

Hiberate 一对一映射注解示例

原文: https://howtodoinjava.com/hibernate/hibernate-one-to-one-mapping-using-annotations/

如果您正在处理任何 Hiberate 项目,或者计划将来进行任何处理,那么您可以轻松了解应用中多个实体之间的一对一关系。 在此 Hibernate 一对一映射示例中,我们将讨论 Hibernate 支持的此映射的 3 种不同变体。

Table fo contents

Various supported techniques for one to one mapping
1\. Using foreign key association
2\. Using common join table
3\. Using shared primary key

对于此 Hiberate 一对一映射示例,我扩展了为 Hiberate HelloWorld 示例编写的示例。 这里有两个实体:EmployeeAccount

一名员工可以拥有一个帐户。 同样,一个帐户将仅与一个员工关联。 在此示例中,这是一对一的关系。

各种支持的技术

在 Hiberate 下,有 3 种方法可在两个实体之间创建一对一关系。 无论哪种方式,我们都必须使用@OneToOne注解。

  1. 第一种技术使用最广泛,并且在其中一个表中使用外键列
  2. 第二种技术使用一种众所周知的解决方案,即具有第三张表来存储前两个表之间的映射。
  3. 第三种技术是新技术,它在两个表中都使用了公共主键值

1. 使用外键关联的 Hiberate 一对一映射

在这种关联中,在所有者实体中创建了一个外键列。 例如,如果我们使为EmployeeEntity为所有者,则将在Employee表中创建一个额外的列"ACCOUNT_ID"。 此列将存储Account表的外键。

表结构将如下所示:

foreign key association one to one

要进行这种关联,请按如下所示引用EmployeeEntity类中的Account实体:


@OneToOne
@JoinColumn(name="ACCOUNT_ID")
private AccountEntity account;

连接列用@JoinColumn注解声明,看起来像 @Column 注解。 它还有一个名为referencedColumnName的参数。 此参数在目标实体中声明将用于连接的列。

如果在所有者方未声明@JoinColumn,则使用默认值。 将在所有者表中创建一个连接列,其名称将是所有者端关系名称_(下划线)和所拥有的主键列名称的连接。 侧。

在双向关系中,一方(只有一方)必须是所有者。 所有者负责关联列的更新。 为了声明对关系不负责的一方,使用了mappedBy属性mappedBy”是指所有者一方的关联的属性名称。


@OneToOne(mappedBy="account")
private EmployeeEntity employee;

在“mappedBy”属性上方,它声明依赖于所有者实体进行映射。

让我们在运行的代码中测试上述映射:


public class TestForeignKeyAssociation {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();

		AccountEntity account = new AccountEntity();
		account.setAccountNumber("123-345-65454");

		// Add new Employee object
		EmployeeEntity emp = new EmployeeEntity();
		emp.setEmail("demo-user@mail.com");
		emp.setFirstName("demo");
		emp.setLastName("user");

		// Save Account
		session.saveOrUpdate(account);
		// Save Employee
		emp.setAccount(account);
		session.saveOrUpdate(emp);

		session.getTransaction().commit();
		HibernateUtil.shutdown();
	}
}

运行以上代码可在数据库中创建所需的架构,然后运行这些 SQL 查询。


Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)

当您运行上述程序时,可以在两个表中验证数据和映射。

2. 使用公共连接表的 Hiberate 一对一映射

这种方法对我们所有人都不陌生。 让我们从这种技术的目标 DB 结构开始。

join table one to one mapping

在该技术中,要使用的主要注解是@JoinTable此注解用于定义两个表中的新表名(强制性)和外键。 让我们看看它的用法:

@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name="EMPLOYEE_ACCCOUNT", joinColumns = @JoinColumn(name="EMPLOYEE_ID"),
inverseJoinColumns = @JoinColumn(name="ACCOUNT_ID"))
private AccountEntity account;

@JoinTable注解在EmployeeEntity类中使用。 它声明将使用两列EMPLOYEE_IDEMPLOYEE表的主键)和ACCOUNT_IDACCOUNT表的主键)创建一个新表EMPLOYEE_ACCOUNT

测试以上实体会在日志文件中生成以下 SQL 查询:

Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: insert into EMPLOYEE_ACCCOUNT (ACCOUNT_ID, EMPLOYEE_ID) values (?, ?)

3. 使用共享主键的 Hiberate 一对一映射

在这种技术中,Hiberate 将确保在两个表中都使用一个公共的主键值。 这样,EmployeeEntity的主键也可以安全地假定为AccountEntity的主键。

表结构将如下所示:

shared primary key one to one

在这种方法中,@PrimaryKeyJoinColumn是要使用的主要注解。 让我们看看如何使用它。


@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private AccountEntity account;

AccountEntity端,它将仍然依赖于所有者实体进行映射。


@OneToOne(mappedBy="account", cascade=CascadeType.ALL)
private EmployeeEntity employee;

测试以上实体会在日志文件中生成以下 SQL 查询:

Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)

因此,我们已经看到所有 3 种不同的方式来创建 Hiberate 中支持的一对一映射。 我建议您下载源代码并使用它。

学习愉快!

下载源码