Hibernate入门之一对一实体映像

一对一实体映像的两种方式:

 

一、外键的关联的方式:
假设我们之前范例的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.sourceforge.net/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配置如下:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping 
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" 
"http://hibernate.sourceforge.net/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.sourceforge.net/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.sourceforge.net/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) 

 

 

以上来自:http://www.360doc.com/content/07/0715/09/16915_611884.shtml

http://www.360doc.com/userhome.aspx?userid=16915&cid=4#

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值