分享

Hibernate入门之一对一实体映像

 WindySky 2007-07-15
一对一实体映像
假设我们之前范例的User与Room是一对一的关系,也就是每一个人分配一个房间,先看看这两个类别:
User.java
package onlyfun.caterpillar;

public class User {
private long id;
private String name;
private Room room;

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Room getRoom() {
return room;
}

public void setRoom(Room room) {
this.room = room;
}
}
Room.java
package onlyfun.caterpillar;

public class Room {
private long id;
private String address;
private User user;

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
 要映像User与Room的一对一关系,我们可以有两种方式,一种是透过外键参考,在之前的多对一的例子中即使外键参考的例子,我们现在限制多对一为一对一,只要在User.hbm.xml中的<many-to-one>上加上unique="true",表示限制一个User有一独有的 Room:
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate./hibernate-mapping-2.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.User" table="USER">

<id name="id" column="USER_ID" unsaved-value="0">
<generator class="increment"/>
</id>

<property name="name">
<column name="NAME" length="16" not-null="true"/>
</property>

<many-to-one name="room"
column="ROOM_ID"
class="onlyfun.caterpillar.Room"
cascade="all"
unique="true"/>
</class>

</hibernate-mapping>
 这就完成了单向的一对一映射,我们可以在Room.hbm.xml上加入参考回User的设定,使其成为双向的一对一映射,如下:
Room.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate./hibernate-mapping-2.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.Room" table="ROOM">

<id name="id" column="ROOM_ID" unsaved-value="0">
<generator class="increment"/>
</id>

<property name="address" type="string"/>

<one-to-one name="user"
class="onlyfun.caterpillar.User"
property-ref="room"/>
</class>

</hibernate-mapping>
 在<one-to-one>的设定中,我们告诉Hibernate,Room返向参考回User的room属性。
 使用以下的程序来测试数据的储存:
HibernateTest.java
import onlyfun.caterpillar.*;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

public class HibernateTest {
public static void main(String[] args) throws HibernateException {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

Room room = new Room();
room.setAddress("NTU-M8-419");

User user1 = new User();
user1.setName("bush");

user1.setRoom(room);
room.setUser(user1);

Session session = sessionFactory.openSession();
Transaction tx= session.beginTransaction();
session.save(user1);

tx.commit();
session.close();

sessionFactory.close();
}
}
 数据表的实际例子,与多对一映像时相同,只不过现在一个User只能对应一个Room。
 另一个映像一对一的方式是使用主键关联,限制两个数据表的主键使用相同的值,如此一个User与Room就是一对一关系,在User.hbm.xml这边,只要使用<one-to-one>设定关联即可:
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate./hibernate-mapping-2.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.User" table="USER">

<id name="id" column="USER_ID" unsaved-value="0">
<generator class="increment"/>
</id>

<property name="name">
<column name="NAME" length="16" not-null="true"/>
</property>

<one-to-one name="room"
class="onlyfun.caterpillar.Room"
cascade="all"/>
</class>
 在Room.hbm.xml这边,必须限制其主键与User的主键相同,而在属性上,使用constrained="true"告诉Hibernate参考至User的主键:
Room.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate./hibernate-mapping-2.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.Room" table="ROOM">

<id name="id" column="ROOM_ID" unsaved-value="0">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>

<property name="address" type="string"/>

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

</hibernate-mapping>
 只要改变映像文件即可,程序的部份无需修改,数据库中的实际储存例子如下:
mysql> select * from USER;
+---------+-------------+
| USER_ID | NAME |
+---------+-------------+
| 1 | bush |
| 2 | caterpillar |
+---------+-------------+
2 rows in set (0.00 sec)

mysql> select * from ROOM;
+---------+------------+
| ROOM_ID | address |
+---------+------------+
| 1 | NTU-M8-419 |
| 2 | NTU-M8-420 |
+---------+------------+
2 rows in set (0.00 sec)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多