好好学习,天天向上!

Hibernate映射一对一关联(之一)

单向一对一是单向多对一的一种特殊情况,可以使用单向多对一实现。只要在多的一面,指定unique="true",即可,例如在学生的映射文件中配置:

<many-to-one name="teacher"
            column="id"
            class="org.shirdrn.entity.Teacher"
            insert="false"
            update="false"
            cascade="all"
            unique="true">
        </many-to-one>

说明一个学生对应一个教师,这里如果教师的类型是家庭教师,教师对学生也是一对一关联。

下面做个测试的例子:

建立数据库hibernate,表person和card,即人和身份证,表的结构如图所示:

person表:

 

Hibernate映射一对一关联(之一) - xinghe - 梦幻心情

card表:

 

Hibernate映射一对一关联(之一) - xinghe - 梦幻心情

第一种方式:使用one-to-many或者many-to-one配置一对一关联

先看一下一对一单向关联(以Person与Card的关联为例,即在Person一方配置与Card的关联):

映射文件及其POJO如下:

Person.hbm.xml和Person.java分别如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="org.shirdrn.entity.Person" table="person" schema="dbo" catalog="hibernate">
        <id name="id" type="java.lang.String">
            <column name="id" length="50" />
            <generator class="assigned" />
        </id>
        <many-to-one name="card"
            class="org.shirdrn.entity.Card"
            update="false"
            insert="false"
            cascade="save-update">
            <column name="id" length="50" not-null="true" unique="true" />
        </many-to-one>
        <property name="name" type="java.lang.String">
            <column name="name" length="50" not-null="true" />
        </property>
        <property name="gender" type="java.lang.String">
            <column name="gender" length="10" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="age" />
        </property>
        <property name="addr" type="java.lang.String">
            <column name="addr" length="50" />
        </property>
    </class>
</hibernate-mapping>

 

package org.shirdrn.entity;

/**
* Person generated by MyEclipse - Hibernate Tools
*/

public class Person implements java.io.Serializable {
    // Fields   

     private String id;
     private Card card;
     private String name;
     private String gender;
     private Integer age;
     private String addr;


    // Constructors

    /** default constructor */
    public Person() {
    }

/** minimal constructor */
    public Person(String id, Card card, String name) {
        this.id = id;
        this.card = card;
        this.name = name;
    }
   
    /** full constructor */
    public Person(String id, Card card, String name, String gender, Integer age, String addr) {
        this.id = id;
        this.card = card;
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.addr = addr;
    }

  
    // Property accessors

    public String getId() {
        return this.id;
    }
   
    public void setId(String id) {
        this.id = id;
    }

    public Card getCard() {
        return this.card;
    }
   
    public void setCard(Card card) {
        this.card = card;
    }

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

    public String getGender() {
        return this.gender;
    }
   
    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getAge() {
        return this.age;
    }
   
    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddr() {
        return this.addr;
    }
   
    public void setAddr(String addr) {
        this.addr = addr;
    }
}

Card.hbm.xml和Card.java分别如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="org.shirdrn.entity.Card" table="card" schema="dbo" catalog="hibernate">
        <id name="id" type="java.lang.String">
            <column name="id" length="50" />
            <generator class="assigned" />
        </id>
        <property name="cardNo" type="java.lang.String">
            <column name="cardNo" length="50" not-null="true" />
        </property>
        <property name="releaseTime" type="java.util.Date">
            <column name="releaseTime" length="23" not-null="true" />
        </property>
        <property name="releaseArea" type="java.lang.String">
            <column name="releaseArea" length="10" not-null="true" />
        </property>
        <property name="effectTime" type="java.lang.Integer">
            <column name="effectTime" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

package org.shirdrn.entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;


/**
* Card generated by MyEclipse - Hibernate Tools
*/

public class Card implements java.io.Serializable {


    // Fields   

     private String id;
     private String cardNo;
     private Date releaseTime;
     private String releaseArea;
     private Integer effectTime;


    // Constructors

    /** default constructor */
    public Card() {
    }

/** minimal constructor */
    public Card(String id, String cardNo, Date releaseTime, String releaseArea, Integer effectTime) {
        this.id = id;
        this.cardNo = cardNo;
        this.releaseTime = releaseTime;
        this.releaseArea = releaseArea;
        this.effectTime = effectTime;
    }

  
    // Property accessors

    public String getId() {
        return this.id;
    }
   
    public void setId(String id) {
        this.id = id;
    }

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

    public Date getReleaseTime() {
        return this.releaseTime;
    }
   
    public void setReleaseTime(Date releaseTime) {
        this.releaseTime = releaseTime;
    }

    public String getReleaseArea() {
        return this.releaseArea;
    }
   
    public void setReleaseArea(String releaseArea) {
        this.releaseArea = releaseArea;
    }

    public Integer getEffectTime() {
        return this.effectTime;
    }
   
    public void setEffectTime(Integer effectTime) {
        this.effectTime = effectTime;
    }
}

在Person.hbm.xml中配置了many-to-one,unique="true"说明是一对一单向关联,而且 cascade="save-update",级联存储更新。

测试程序如下:

package org.shirdrn.test;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.shirdrn.HibernateSessionFactory;
import org.shirdrn.entity.Card;
import org.shirdrn.entity.Person;

public class MyTest {
public static void main(String[] args){
   Session session = HibernateSessionFactory.getSession();
   Transaction tx = null;
   try{
    tx = session.beginTransaction();
    Person p = new Person();
    p.setId("222403199901011113");
    p.setName("刘备");
    Card c = new Card();
    c.setId("222403199901011113");
    c.setCardNo("JL-2008-03-04-0001");
    c.setReleaseTime(new Date());
    c.setReleaseArea("长春");
    c.setEffectTime(new Integer(20));
    p.setCard(c);
    session.save(p);
    tx.commit();
   }
   catch(Exception e){
    tx.rollback();
    e.printStackTrace();
   }
   finally{
    HibernateSessionFactory.closeSession();
   }
}

}

查看结果如下:

Hibernate: select card_.id, card_.cardNo as cardNo3_, card_.releaseTime as releaseT3_3_, card_.releaseArea as releaseA4_3_, card_.effectTime as effectTime3_ from hibernate.dbo.card card_ where card_.id=?
Hibernate: insert into hibernate.dbo.card (cardNo, releaseTime, releaseArea, effectTime, id) values (?, ?, ?, ?, ?)
Hibernate: insert into hibernate.dbo.person (name, gender, age, addr, id) values (?, ?, ?, ?, ?)

执行了两次insert操作,存储数据成功。

反过来,在Card.hbm.xml中配置与Person的关联,如果使用many-to-one配置一对一单向关联,过程和上面的是一样的。

现在我们使用one-to-many配置一对一单向关联:

其实,在我们指定了“多”的一方的时候(如Card),如果没有限制的话(比如这里要求配置一对一),它对于“一”的一方来说就是一对一或者一对多,无论是在“一”的一方配置一对一或者一对多,对单向关联都没有影响,因为“多”的一方可以单条记录操作(如果是一对一),也可以多条记录操作(如果是一对多),参照的就是另一方。

在上面的基础上,把Person.hbm.xml中的

<many-to-one name="card"
            class="org.shirdrn.entity.Card"
            update="false"
            insert="false"
            cascade="save-update">
            <column name="id" length="50" not-null="true" unique="true" />
</many-to-one>

去掉,改为在card.hbm.xml中配置one-to-many如下:

<set name="persons"
        inverse="true"
        cascade="save-update">
            <key>
                <column name="id" length="50" not-null="true" unique="true" />
            </key>
            <one-to-many class="org.shirdrn.entity.Person" />
</set>

并且,要在Card的POJO里面添加Field:

private Set persons = new HashSet(0);

以及:

public Set getPersons() {
        return this.persons;
}
    
public void setPersons(Set persons) {
        this.persons = persons;
   }

测试程序如下:

package org.shirdrn.test;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.shirdrn.HibernateSessionFactory;
import org.shirdrn.entity.Card;
import org.shirdrn.entity.Person;

public class MyTest {
public static void main(String[] args){
   Session session = HibernateSessionFactory.getSession();
   Transaction tx = null;
   try{
    tx = session.beginTransaction();
    Person p = new Person();
    p.setId("222403199901011116");
    p.setName("刘备");
    Set hs = new HashSet();
    hs.add(p);
    Card c = new Card();
    c.setId("222403199901011116");
    c.setCardNo("JL-2008-03-04-0001");
    c.setReleaseTime(new Date());
    c.setReleaseArea("长春");
    c.setEffectTime(new Integer(20));
    p.setCard(c);
    c.setPersons(hs);
    session.save(c);
    tx.commit();
   }
   catch(Exception e){
    tx.rollback();
    e.printStackTrace();
   }
   finally{
    HibernateSessionFactory.closeSession();
   }
}

}

执行结果如下:

Hibernate: select person_.id, person_.name as name2_, person_.gender as gender2_, person_.age as age2_, person_.addr as addr2_ from hibernate.dbo.person person_ where person_.id=?
Hibernate: insert into hibernate.dbo.card (cardNo, releaseTime, releaseArea, effectTime, id) values (?, ?, ?, ?, ?)
Hibernate: insert into hibernate.dbo.person (name, gender, age, addr, id) values (?, ?, ?, ?, ?)

级联保存成功。

这里,是先把要insert的数据set到Person对象中,然后把Person对象放到HashSet中,通过配置的集合映射及其关联,把存有Person对象的HashSet正确地set到Card的对象中,然后可以insert我们处理过的Card对象了,而且级联insert了Card对象。

 

posted @ 2013-01-11 11:13  忍性而为  阅读(177)  评论(0编辑  收藏  举报
好好学习,天天向上!