one-to-one 一对一主键关联映射_单向

one-to-one 一对一主键关联映射_单向

一对一主键关联映射——关联的两个实体共享一个主键(让两个实体对象的id保持相同),这样可以避免多余的字段被创建 .

(单向关联Person---->IdCard)


类:

public class IdCard {

private Integer id;
private String idNo;

}


public class Person {

private Integer id;
private String name;
private IdCard idCard;

}


hbm.xml

IdCard.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.model">
    <class name="IdCard" table="idcard1" >
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="native" />
        </id>
        <property name="idNo" column="id_no" type="java.lang.String" />
    </class>

</hibernate-mapping>


Person.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zd.model">
    <class name="Person" table="person1" >
        <id name="id" column="id" type="java.lang.Integer">

<!-- person的主键来源idCard,也就是共享idCard的主键 -->
            <generator class="foreign">
                <param name="property">idCard</param>
            </generator>
        </id>
        <property name="name" column="name" length="50" type="java.lang.String" />

<one-to-one name="idCard" ></one-to-one>
<!--one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,

one-to-one的属性cascade=all ,即新增Person时,同时可新增idcard,

constrained="true", 表明当前主键上存在一个约束,person的主键作为外键参照了idCard 
        <one-to-one name="idCard" constrained="true"></one-to-one>

-->
    </class>

</hibernate-mapping>




运用例子:

public void testSave1(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    IdCard idCard = new IdCard();
    idCard.setIdNo("88888888888888");
    Person p = new Person();
    p.setName("Tom");
    p.setIdCard(idCard);

//session.save(idCard); //可删除,因one-to-one 默认casedese=all
    session.save(p); // 保存idCard, person2个。
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
     ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }
 
}



Hibernate: insert into idcard1 (id_no) values (?)
Hibernate: insert into person1 (name, id) values (?, ?)



public void testGet1(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    Person p = (Person) session.get(Person.class, new Integer(2));
   System.out.println("person.name=" + p.getName());
    System.out.println("idCard.cardNo=" + p.getIdCard().getIdNo());
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
     ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }
 
}


Hibernate: select person0_.id as id1_0_, person0_.name as name1_0_ from person1 person0_ where person0_.id=?
person.name=Tom
Hibernate: select idcard0_.id as id0_0_, idcard0_.id_no as id2_0_0_ from idcard1 idcard0_ where idcard0_.id=?
idCard.cardNo=88888888888888



===================================================================

戓要改为双向,修改以下:

public class IdCard {

private Integer id;
private String idNo;
private Person person; //加个对象变量



IdCard.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zd.model">
    <class name="IdCard" table="idcard1" >
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="native" />
        </id>
        <property name="idNo" column="id_no" type="java.lang.String" />
        <one-to-one name="person"></one-to-one>
    </class>

</hibernate-mapping>


测试用例:

public void testGet2(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
   IdCard ic = (IdCard)session.get(IdCard.class, new Integer(1));
    System.out.println("IdCard.idNo =" + ic.getIdNo());
    System.out.println("Person.name = " + ic.getPerson().getName());
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
     ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }
 
}

执行一条sql语句,且是join, 因为one-to-one默认是fetch="join"

Hibernate: select idcard0_.id as id0_1_, idcard0_.id_no as id2_0_1_, person1_.id as id1_0_, person1_.name as name1_0_ from idcard1 idcard0_ left outer join person1 person1_ on idcard0_.id=person1_.id where idcard0_.id=?
IdCard.idNo =88888888888888
Person.name = Tom

若IdCard.hbm.xml 中<one-to-one name="person" fetch="select"></one-to-one> ,执行2条sql

Hibernate: select idcard0_.id as id0_0_, idcard0_.id_no as id2_0_0_ from idcard1 idcard0_ where idcard0_.id=?
Hibernate: select person0_.id as id1_0_, person0_.name as name1_0_ from person1 person0_ where person0_.id=?
IdCard.idNo =88888888888888
Person.name = Tom



================================

fetch取值"select",表示序列选择抓取,还有一个值是"join",表示采用外连接抓取。

你可能感兴趣的:(one-to-one)