Hibernate one-to-one映射的三种方式

几种支持的技术

在Hibernate中,在两个实体间有三种方式创建one-to-one的关系,其中一种方式是使用@OneToOne注解。第一种技术广泛的被使用,在表中使用外键列;第二种技术使用众所周知的第三个表,来存储两个表间的映射关系;第三种技术是在两个表中使用普通的主键。

我们一个一个来看看

使用主键的关系

在这种关系中,外键列在自己的实体中创建,例如我们让 Employee实体作为拥有者,那么外键列ACCOUNT_ID将会在Employee表中被创建,这一列将为Account表存储外键

表的结构如下:

为了建立这种联系,在Employee实体类中如下指定account实体

 
  1. @OneToOne

  2. @JoinColumn(name="ACCOUNT_ID")

  3. private AccountEntity account;


join列使用 @JoinColumn注解声明,这很像@Column注解。它有很多参数指定列名,这个参数声明了将要join的目标实体的列。如果没有@JoinColumn在拥有端进行声明的话,它是默认增加的。它的名字将会连接拥有端_(下划线)和被拥有端的主键列。在双向的关系中,一边(仅仅一边)必须要作为拥有者,拥有者负责关联列的更新。为了声明另一边不负责这个关系,可以使用mappedBy。mappedBy指的是关联的拥有者端的属性的名字

 
  1. @OneToOne(mappedBy="account")

  2. private EmployeeEntity employee;


上边的属性声明了它依赖于拥有实体的映射关系

我们来测试一下上边的映射关系

 
  1. public class TestForeignKeyAssociation {

  2.  
  3. public static void main(String[] args) {

  4. Session session = HibernateUtil.getSessionFactory().openSession();

  5. session.beginTransaction();

  6.  
  7. AccountEntity account = new AccountEntity();

  8. account.setAccountNumber("123-345-65454");

  9.  
  10. // Add new Employee object

  11. EmployeeEntity emp = new EmployeeEntity();

  12. emp.setEmail("demo-user@mail.com");

  13. emp.setFirstName("demo");

  14. emp.setLastName("user");

  15.  
  16. // Save Account

  17. session.saveOrUpdate(account);

  18. // Save Employee

  19. emp.setAccount(account);

  20. session.saveOrUpdate(emp);

  21.  
  22. session.getTransaction().commit();

  23. HibernateUtil.shutdown();

  24. }

  25. }


运行结果:

 
  1. Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)

  2. Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)

  3.  

 

使用普通的连接表

这种方法对我们来说并不是新的方法,我们从它的关系表开始

在这种技术中,主要使用的标签是@JoinTable,这种标签定义新表的名字(强制性的)和两个表的外键,我们来看一下他们是怎么使用的

 
  1. @OneToOne(cascade = CascadeType.ALL)

  2. @JoinTable(name="EMPLOYEE_ACCCOUNT", joinColumns = @JoinColumn(name="EMPLOYEE_ID"),

  3. inverseJoinColumns = @JoinColumn(name="ACCOUNT_ID"))

  4. private AccountEntity account;


@JoinTable注解用在Employee实体类中,被声明为一个新的表EMPLOYEE_ACCOUNT将会创建两个列EMPLOYEE_ID(EMPLOYEE表的主键)和ACCOUNT_ID(ACCOUNT表的主键),测试上述的实体将会产生下边的SQL结果

 
  1. Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)

  2. Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)

  3. Hibernate: insert into EMPLOYEE_ACCCOUNT (ACCOUNT_ID, EMPLOYEE_ID) values (?, ?)

  4.  

 

使用共享主键

在这种技术中,Hibernate将会确保在两个表中使用了普通的主键。这种方式Employee的实体主键可以被安全的假定为Account实体的主键

表间的结构图如下:

这种方式,主要使用的是@PrimaryKeyJoinColumn注解

 
  1. @OneToOne(cascade = CascadeType.ALL)

  2. @PrimaryKeyJoinColumn

  3. private AccountEntity account;


在Account实体的那一边,依旧根据拥有者边的映射关系

 
  1. @OneToOne(mappedBy="account", cascade=CascadeType.ALL)

  2. private EmployeeEntity employee;


测试上边实体的映射关系

 
  1. Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)

  2. Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)

  3.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值