关于hibernate中双向外键关联one-to-one的property-ref=的问题




2011-07-06 18:19:14|  分类: 默认分类 |  标签:hibernate  property-ref   |字号 订阅
大家都知道hibernate中的one-to-one映射主要有两种策略,(1)一对一主键关联(单向和双向)。(2)一对一外键映射(单项和双向)。本文主要讲解一下,一对一外键映射中的双向问题,在此前先通过一个实例了解。 


  person和idCard,是一种一对一的关系,其中 
  
t_person表                               
id        name       idCard(unique) 
1         张三      
2   王五       1 


其中王五是没有idcard,这也符合现实中的,有些人是没有身份证的。 
t_idCard表 
id         cardNo 
1    11111111111111 




实体类: 
    IdCard 
package com.bjpowernode.hibernate; 


public class IdCard { 


private int id; 


private String cardNo; 


private Person person; 


public Person getPerson() { 
return person; 



public void setPerson(Person person) { 
this.person = person; 



public int getId() { 
return id; 



public void setId(int id) { 
this.id = id; 



public String getCardNo() { 
return cardNo; 



public void setCardNo(String cardNo) { 
this.cardNo = cardNo; 








             Person 
package com.bjpowernode.hibernate; 


public class Person { 


private int id; 


private String name; 


private IdCard idCard; 


public int getId() { 
return id; 



public void setId(int id) { 
this.id = id; 



public String getName() { 
return name; 



public void setName(String name) { 
this.name = name; 



public IdCard getIdCard() { 
return idCard; 



public void setIdCard(IdCard idCard) { 
this.idCard = idCard; 




(3)配置文件 
   IdCard的: 
  <?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="com.bjpowernode.hibernate"> 
<class name="IdCard" table="t_idCard"> 
<id name="id"> 
<generator class="native"/> 
</id> 
<property name="cardNo"/> 
<one-to-one name="person"  class="Person"  /> 
</class> 
</hibernate-mapping> 


Person的: 


<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="com.bjpowernode.hibernate"> 
<class name="Person" table="t_person"> 
<id name="id"> 
<generator class="native"/> 
</id> 
<property name="name"/> 
<many-to-one name="idCard" cascade="all" class="IdCard" 
unique="true" column="card_ID" /> 
</class> 
</hibernate-mapping> 
(3) 
向t_person中插入数据: 
import org.hibernate.Session; 


import junit.framework.TestCase; 


public class One2OneTest extends TestCase { 


public void testSave1() { 
Session session = null; 
try { 
session = HibernateUtils.getSession(); 
session.beginTransaction(); 


Person person = new Person(); 
person.setName("张三"); 


session.save(person); 
session.getTransaction().commit(); 
}catch(Exception e) { 
e.printStackTrace(); 
session.getTransaction().rollback(); 
}finally { 
HibernateUtils.closeSession(session); 


结果如下: 
mysql> select * from t_person; 
+----+------+---------+ 
| id | name | card_ID | 
+----+------+---------+ 
|  1 | 张三 |    NULL | 
+----+------+---------+ 
1 row in set (0.00 sec) 


mysql> select * from t_idcard; 
Empty set (0.00 sec) 


在插入数据: 
public void testSave2() { 
Session session = null; 
try { 
session = HibernateUtils.getSession(); 
session.beginTransaction(); 


IdCard idCard = new IdCard(); 
idCard.setCardNo("1111111111"); 
session.save(idCard); 


Person person = new Person(); 
person.setName("王五"); 
//建立关联 
person.setIdCard(idCard); 


session.save(person); 


session.getTransaction().commit(); 
}catch(Exception e) { 
e.printStackTrace(); 
session.getTransaction().rollback(); 
}finally { 
HibernateUtils.closeSession(session); 


数据库中的结果如下: 
mysql> select * from t_person; 
+----+------+---------+ 
| id | name | card_ID | 
+----+------+---------+ 
|  1 | 张三 |    NULL | 
|  2 | 王五 |       1 | 
+----+------+---------+ 
2 rows in set (0.00 sec) 


mysql> select * from t_idcard; 
+----+------------+ 
| id | cardNo     | 
+----+------------+ 
|  1 | 1111111111 | 
+----+------------+ 
1 row in set (0.00 sec) 
(4)加载数据,这样的话就可以从person的一端加载到idCard, 
如下: 
public void testLoad1() { 
Session session = null; 
try { 
session = HibernateUtils.getSession(); 
session.beginTransaction(); 
Person person = (Person)session.load(Person.class, 2); 
System.out.println("person.name=" + person.getName()); 
System.out.println("person.cardNo=" +                   person.getIdCard().getCardNo()); 
session.getTransaction().commit(); 
}catch(Exception e) { 
e.printStackTrace(); 
session.getTransaction().rollback(); 
}finally { 
HibernateUtils.closeSession(session); 


结果如下: 
    Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_, person0_.card_ID as card3_0_0_ from t_person person0_ where person0_.id=? 
person.name=王五 
        Hibernate: select idcard0_.id as id1_1_, idcard0_.cardNo as cardNo1_1_, person1_.id as id0_0_, person1_.name as name0_0_, person1_.card_ID as card3_0_0_ from t_idCard idcard0_ left outer join t_person person1_ on idcard0_.id=person1_.id where idcard0_.id=? 
    person.cardNo=1111111111 这样的就找到了person对应的idcard,那能不能有idCard找到person呢? 


public void testLoad2() { 
Session session = null; 
try { 
session = HibernateUtils.getSession(); 
session.beginTransaction(); 
//                      
IdCard idCard = (IdCard)session.load(IdCard.class, 1); 
System.out.println("idCard.cardNo=" + idCard.getCardNo()); 
System.out.println("idCard.person.name=" + idCard.getPerson().getName()); 
session.getTransaction().commit(); 
}catch(Exception e) { 
e.printStackTrace(); 
session.getTransaction().rollback(); 
}finally { 
HibernateUtils.closeSession(session); 


结果如下: 
Hibernate: select idcard0_.id as id1_1_, idcard0_.cardNo as cardNo1_1_, person1_.id as id0_0_, person1_.name as name0_0_, person1_.card_ID as card3_0_0_ from t_idCard idcard0_ left outer join t_person person1_ on idcard0_.id=person1_.id where idcard0_.id=? 
idCard.cardNo=1111111111 
idCard.person.name=张三 
结果对吗? 
  肯定不对,idCard.cardNo=1111111111这是王五的idCard,怎么查出来张三的呢?原因在于: 


idCard的配置文件问题: 
应该在idCard的配置文件的<one-to-one name="person"  class="Person"  /> 
修改为<one-to-one name="person"  class="Person"  property-ref="idCard"/> 
因为:如果不修改则idCard会根据自己的id和person中的id比较(因为one-to-one是通过id查找到的),这样是不符合要求的,因为我们t_idcard中的id和t_person中 Card_ID相比较,这样的话可以通过 
property-ref="idCard" 的设置找到t_person表中Card_ID和它作比较找到我们要找的数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值