• 关​于​h​i​b​e​r​n​a​t​e​中​双​向​外​键​关​联​o​n​e​-​t​o​-​o​n​e​的​p​r​o​p​e​r​t​y​-​r​e​f​=​的​问​题(转)


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

  • 相关阅读:
    sizeof注意
    如何获取存储过程的返回值和输出值
    OA、ERP、SRM、PLM、CAPP、MES、LIMS、CRM
    js1号脚本
    Python各类常用库整理
    Html设计器
    python从入门到放弃之图像处理
    C# Web API操作Sqlite数据库
    C# Naudio 从麦克风输入到声卡输出 录音 放音功能
    WPF/MVVM模式入门教程(二):实现INotifyPropertyChanged接口
  • 原文地址:https://www.cnblogs.com/sandea/p/3878767.html
Copyright © 2020-2023  润新知