zoukankan      html  css  js  c++  java
  • 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对象。

     

  • 相关阅读:
    MySQL存储引擎InnoDB与Myisam的六大区别
    PHP+mysql防止SQL注入
    HTTPS 的实现原理
    如何保障 API 接口的安全性?
    使用Merge存储引擎实现MySQL分表
    彻底搞懂Reactor模型和Proactor模型
    REDIS集群脑裂以及解决方案
    linux shell文件合并 去重 分割
    python fnmatch & glob
    sed初理多行合并+sed之G、H、g、h使用+sed n/N使用说明
  • 原文地址:https://www.cnblogs.com/a1280055207/p/2856051.html
Copyright © 2011-2022 走看看