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

来源:互联网 发布:qq国际网络 编辑:程序博客网 时间:2024/05/24 01:49
大家都知道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 
[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">package com.bjpowernode.hibernate;   
  2.   
  3. public class IdCard {   
  4.   
  5. private int id;   
  6.   
  7. private String cardNo;   
  8.   
  9. private Person person;   
  10.   
  11. public Person getPerson() {   
  12. return person;   
  13. }   
  14.   
  15. public void setPerson(Person person) {   
  16. this.person = person;   
  17. }   
  18.   
  19. public int getId() {   
  20. return id;   
  21. }   
  22.   
  23. public void setId(int id) {   
  24. this.id = id;   
  25. }   
  26.   
  27. public String getCardNo() {   
  28. return cardNo;   
  29. }   
  30.   
  31. public void setCardNo(String cardNo) {   
  32. this.cardNo = cardNo;   
  33. }   
  34.   
  35. }   
  36. </span>  


   Person

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">package com.bjpowernode.hibernate;   
  2.   
  3. public class Person {   
  4.   
  5. private int id;   
  6.   
  7. private String name;   
  8.   
  9. private IdCard idCard;   
  10.   
  11. public int getId() {   
  12. return id;   
  13. }   
  14.   
  15. public void setId(int id) {   
  16. this.id = id;   
  17. }   
  18.   
  19. public String getName() {   
  20. return name;   
  21. }   
  22.   
  23. public void setName(String name) {   
  24. this.name = name;   
  25. }   
  26.   
  27. public IdCard getIdCard() {   
  28. return idCard;   
  29. }   
  30.   
  31. public void setIdCard(IdCard idCard) {   
  32. this.idCard = idCard;   
  33. }   
  34. }   
  35. </span>  


(3)配置文件
   IdCard的:
 

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;"> <?xml version="1.0"?>   
  2. <!DOCTYPE hibernate-mapping PUBLIC   
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">   
  5. <hibernate-mapping package="com.bjpowernode.hibernate">   
  6. <class name="IdCard" table="t_idCard">   
  7. <id name="id">   
  8. <generator class="native"/>   
  9. </id>   
  10. <property name="cardNo"/>   
  11. <one-to-one name="person"  class="Person"  />   
  12. </class>   
  13. </hibernate-mapping>   
  14. </span>  


Person的:

[html] view plain copy print?
  1. <span style="font-family:SimHei;"><span style="font-size:18px;color:#000000;"><?xml version="1.0"?>   
  2. <!DOCTYPE hibernate-mapping PUBLIC   
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">   
  5. <hibernate-mapping package="com.bjpowernode.hibernate">   
  6. <class name="Person" table="t_person">   
  7. <id name="id">   
  8. <generator class="native"/>   
  9. </id>   
  10. <property name="name"/>   
  11. <many-to-one name="idCard" cascade="all" class="IdCard"   
  12. unique="true" column="card_ID" />   
  13. </class>   
  14. </hibernate-mapping>   
  15.   
  16. </span><span style="font-size:18px;color:#000000;">(3)</span></span><span style="color:#000000;"><span style="font-family:SimHei;font-size:18px;">   
  17. 向t_person中插入数据: </span></span>  
[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">import org.hibernate.Session;   
  2.   
  3. import junit.framework.TestCase;   
  4.   
  5. public class One2OneTest extends TestCase {   
  6.   
  7. public void testSave1() {   
  8. Session session = null;   
  9. try {   
  10. session = HibernateUtils.getSession();   
  11. session.beginTransaction();   
  12.   
  13. Person person = new Person();   
  14. person.setName("张三");   
  15.   
  16. session.save(person);   
  17. session.getTransaction().commit();   
  18. }catch(Exception e) {   
  19. e.printStackTrace();   
  20. session.getTransaction().rollback();   
  21. }finally {   
  22. HibernateUtils.closeSession(session);   
  23. </span>  
 

结果如下:

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">mysql> select * from t_person; </span>  

+----+------+---------+
| id | name | card_ID |
+----+------+---------+
|  1 | 张三
|    NULL |
+----+------+---------+
1 row in set (0.00 sec)

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">mysql> select * from t_idcard; </span>  


Empty set (0.00 sec)

在插入数据:

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">public void testSave2() {   
  2. Session session = null;   
  3. try {   
  4. session = HibernateUtils.getSession();   
  5. session.beginTransaction();   
  6.   
  7. IdCard idCard = new IdCard();   
  8. idCard.setCardNo("1111111111");   
  9. session.save(idCard);   
  10.   
  11. Person person = new Person();   
  12. person.setName("王五");   
  13. //建立关联   
  14. person.setIdCard(idCard);   
  15.   
  16. session.save(person);   
  17.   
  18. session.getTransaction().commit();   
  19. }catch(Exception e) {   
  20. e.printStackTrace();   
  21. session.getTransaction().rollback();   
  22. }finally {   
  23. HibernateUtils.closeSession(session);   
  24. }   
  25. </span>  

数据库中的结果如下:

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">mysql> select * from t_person; </span>  

+----+------+---------+
| id | name | card_ID |
+----+------+---------+
|  1 | 张三
|    NULL |
|  2 | 王五
|       1 |
+----+------+---------+
2 rows in set (0.00 sec)

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">mysql> select * from t_idcard; </span>  


+----+------------+
| id | cardNo     |
+----+------------+
|  1 | 1111111111 |
+----+------------+
1 row in set (0.00 sec)
(4)加载数据,这样的话就可以从person的一端加载到idCard,

如下:

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">public void testLoad1() {   
  2. Session session = null;   
  3. try {   
  4. session = HibernateUtils.getSession();   
  5. session.beginTransaction();   
  6. Person person = (Person)session.load(Person.class, 2);   
  7. System.out.println("person.name=" + person.getName());   
  8. System.out.println("person.cardNo=" +                   person.getIdCard().getCardNo());   
  9. session.getTransaction().commit();   
  10. }catch(Exception e) {   
  11. e.printStackTrace();   
  12. session.getTransaction().rollback();   
  13. }finally {   
  14. HibernateUtils.closeSession(session);   
  15. }   
  16. </span>  

结果如下:
    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呢?

[html] view plain copy print?
  1. <span style="font-family:SimHei;font-size:18px;color:#000000;">public void testLoad2() {   
  2. Session session = null;   
  3. try {   
  4. session = HibernateUtils.getSession();   
  5. session.beginTransaction();   
  6. //                        
  7. IdCard idCard = (IdCard)session.load(IdCard.class, 1);   
  8. System.out.println("idCard.cardNo=" + idCard.getCardNo());   
  9. System.out.println("idCard.person.name=" + idCard.getPerson().getName());   
  10. session.getTransaction().commit();   
  11. }catch(Exception e) {   
  12. e.printStackTrace();   
  13. session.getTransaction().rollback();   
  14. }finally {   
  15. HibernateUtils.closeSession(session);   
  16. }   
  17. </span>  


结果如下:
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和它作比较找到我们要找的数据。

 
总结:
property-ref: 指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。
property-ref,不是数据库表中的字段名,而是定义的java类中的属性名,一定要注意。
0 0
原创粉丝点击