zoukankan      html  css  js  c++  java
  • 关于hibernate中双向外键关联onetoone的propertyref=的问题

        大家都知道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和它作比较找到我们要找的数据。

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

     

     

  • 相关阅读:
    powershell网络钓鱼获取用户密码
    js 倒计时(转)
    TFS如何设置在客户端独占签出
    TFS 2010 配置的时候,提示TF255466错误
    浅谈Dynamic 关键字系列之一:dynamic 就是Object(转)
    js替换字符串中全部“-”
    苹果safari浏览器登陆时Cookie无法保存的问题
    IIS发布网站出现“未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。”的解决方法
    Aspose.Cells单元格转换为数字格式
    SQL Server中GO的使用方法(转)
  • 原文地址:https://www.cnblogs.com/CharmingDang/p/9663933.html
Copyright © 2011-2022 走看看