Hibernate (八)一对一 (外键关联方式)

来源:互联网 发布:自选股软件下载 编辑:程序博客网 时间:2024/06/05 21:54

一对一 映射有两种方式:
主键关联: id 对应 id 两个主键必须相同
外键关联: id 对应 xxxid 专门设置一个外键属性 (推荐使用)

外键关联方式

例如:下面的例子IdCard 表会有一个专门的外键属性 personId 对应 person 主键id

IdCard.java

public class IdCard {    private Integer id;    private String number;    private Person person; // 关联的公民

IdCard.hbm.xml

<?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="cn.itcast.i_hbm_oneToOne">    <class name="IdCard" table="idCard">        <id name="id">            <generator class="native"></generator>        </id>        <property name="number"/>        <!-- person属性,Person类型。            表达的是本类与Person的一对一。            采用基于外键的一对一映射方式,本方有外键方。 -->        <many-to-one name="person" class="Person" column="personId" unique="true"></many-to-one>    </class></hibernate-mapping>

Person.java

public class Person {    private Integer id;    private String name;    private IdCard idCard; // 关联的身份证

Person.hbm.xml

<?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="cn.itcast.i_hbm_oneToOne">    <class name="Person" table="person">        <id name="id">            <generator class="native"></generator>        </id>        <property name="name"/>        <!-- idCard属性,IdCard类型。            表达的是本类与IdCard的一对一。            采用基于外键的一对一映射方式,本方无外键方。            property-ref属性:                写的是对方映射中外键列对应的属性名。           -->        <one-to-one name="idCard" class="IdCard" property-ref="person"/>    </class></hibernate-mapping>

第二种方式:

主键关联

其他一样只是,映射文件不同
IdCard.hbm.xml

... ...<hibernate-mapping package="cn.itcast.i_hbm_oneToOne2">    <class name="IdCard" table="idCard2">        <id name="id">            <!-- 当使用基于主键的一对一映射时,                有外键方的主键生成策略一定要是foreign。                参数property:                    生成主键值时所根据的对象。             -->            <generator class="foreign">                <param name="property">person</param>            </generator>        </id>        <property name="number"/>        <!-- person属性,Person类型。            表达的是本类与Person的一对一。            采用基于主键的一对一映射方式,本方有外键方。 -->        <one-to-one name="person" class="Person" constrained="true"></one-to-one>    </class></hibernate-mapping>

Person.hbm.xml

... ...<hibernate-mapping package="cn.itcast.i_hbm_oneToOne2">    <class name="Person" table="person2">        <id name="id">            <generator class="native"></generator>        </id>        <property name="name"/>        <!-- idCard属性,IdCard类型。            表达的是本类与IdCard的一对一。            采用基于主键的一对一映射方式,本方无外键方。         -->        <one-to-one name="idCard" class="IdCard"></one-to-one>    </class></hibernate-mapping>

测试代码

package cn.itcast.i_hbm_oneToOne;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.junit.Test;public class App {    private static SessionFactory sessionFactory = new Configuration()//            .configure()//            .addClass(Person.class)// 添加Hibernate实体类(加载对应的映射文件)            .addClass(IdCard.class)// 添加Hibernate实体类(加载对应的映射文件)            .buildSessionFactory();    // 保存,有关联关系    @Test    public void testSave() throws Exception {        Session session = sessionFactory.openSession();        session.beginTransaction();        // --------------------------------------------        // 新建对象        Person person = new Person();        person.setName("张三");        IdCard idCard = new IdCard();        idCard.setNumber("100000011X");        // 关联起来        // person.setIdCard(idCard);        idCard.setPerson(person);        // 保存        session.save(person);        session.save(idCard);        // --------------------------------------------        session.getTransaction().commit();        session.close();    }    // 获取,可以获取到关联的对方    @Test    public void testGet() throws Exception {        Session session = sessionFactory.openSession();        session.beginTransaction();        // --------------------------------------------        // 获取一方,并显示另一方信息        // Person person = (Person) session.get(Person.class, 1);        // System.out.println(person);        // System.out.println(person.getIdCard());        IdCard idCard = (IdCard) session.get(IdCard.class, 1);        System.out.println(idCard);        System.out.println(idCard.getPerson());        // --------------------------------------------        session.getTransaction().commit();        session.close();    }    // 解除关联关系:一对一中,只能有外键方可以维护关联关系。    @Test    public void testRemoveRelation() throws Exception {        Session session = sessionFactory.openSession();        session.beginTransaction();        // --------------------------------------------        // 从有外键方解除关系,可以。        // IdCard idCard = (IdCard) session.get(IdCard.class, 1);        // idCard.setPerson(null);        // 从无外键方解除关系,不可以。        Person person = (Person) session.get(Person.class, 1);        person.setIdCard(null);        // --------------------------------------------        session.getTransaction().commit();        session.close();    }    // 删除对象,对关联对象的影响    @Test    public void testDelete() throws Exception {        Session session = sessionFactory.openSession();        session.beginTransaction();        // --------------------------------------------        // a, 如果没有关联的对方:能删除。        // b, 如果有关联的对方且可以维护关联关系(有外键方),他就会先删除关联关系,再删除自己。        // c, 如果有关联的对方且不能维护关联关系(无外键方),所以会直接执行删除自己,就会有异常。        IdCard idCard = (IdCard) session.get(IdCard.class, 1);        session.delete(idCard);        // Person person = (Person) session.get(Person.class, 1);        // session.delete(person);        // --------------------------------------------        session.getTransaction().commit();        session.close();    }}
0 0
原创粉丝点击