一對一(主鍵關聯)


一對一關聯的另一種方式,是限制兩個實體的主鍵必須一致,如此直接透過兩個表格的主鍵就可確定一對一關聯,而不用額外的外鍵參考。

一對一


例如user與room表格,可以如下建立:
    create table room (
        id bigint not null,
        address varchar(255),
        primary key (id)
    )

    create table user (
        id bigint not null auto_increment,
        name varchar(255),
        primary key (id)
    )


User類別與Room類別的設計使用 一 對一(唯一外鍵關聯) 中的設計即可,接著在User.hbm.xml方面如下設計:
  • User.hbm.xml
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.User" table="user">
<id name="id" column="id">
<generator class="native"/>
</id>

<property name="name" column="name"/>

<one-to-one name="room"
class="onlyfun.caterpillar.Room"
cascade="all"/>
</class>

</hibernate-mapping>

在Room.hbm.xml的設計方面如下:
  • Room.hbm.xml
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.Room" table="room">
<id name="id" column="id">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>

<property name="address" column="address" />

<one-to-one name="user"
class="onlyfun.caterpillar.User"
constrained="true"/>
</class>

</hibernate-mapping>

在Room的id主鍵上,使用foreign表示與外鍵共享主鍵,也就是與User實體共享主鍵,而constrained設定為true,表示約束 room的主鍵必須與user中對應資料的主鍵相同。

一個儲存的實例如下:
User user1 = new User();
user1.setName("bush");
Room room1 = new Room();
room1.setAddress("NTU-M8-419");
       
// 互相設定關聯
user1.setRoom(room1);
room1.setUser(user1);
       
User user2 = new User();
user2.setName("caterpillar");
Room room2 = new Room();
room2.setAddress("NTU-M8-418");
       
// 互相設定關聯
user2.setRoom(room2);
room2.setUser(user2);
       
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
 
session.save(user1);
session.save(user2);
       
tx.commit();
session.close();

資料庫中將有以下的儲存結果:
mysql> select * from user;
+----+-------------+
| id    | name        |
+----+-------------+
|  1    | bush         |
|  2    | caterpillar |
+----+-------------+
2 rows in set (0.00 sec)

mysql> select * from room;
+----+------------------+
| id    | address          |
+----+------------------+
|  1    | NTU-M8-419 |
|  2    | NTU-M8-418 |
+----+------------------+
2 rows in set (0.00 sec)