Hibernate4从入门到精通六——————ORM之一对一和联合主键实现

来源:互联网 发布:小精灵软件下载 编辑:程序博客网 时间:2024/05/17 04:06


一、一对一关系


二、一对一单向关联项目

1、新建JavaProject

2、在包org.zttc.itat.model下新建

Person.java

package org.zttc.itat.model;public class Person {private int id;private String name;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;}}

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="org.zttc.itat.model">    <class name="Person" table="t_person">        <id name="id">        <!-- 表示不会自动生成,而是需要由用户来指定 -->          <!--   <generator class="assigned"/> -->        <!-- 会自动生成一个字符串,此时组件必须为String类型 -->          <generator class="native"/>        </id>        <property name="name"/>    </class></hibernate-mapping>

IDCard.java

package org.zttc.itat.model;public class IDCard {private int id;private String no;private Person person;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getNo() {return no;}public void setNo(String no) {this.no = no;}public Person getPerson() {return person;}public void setPerson(Person person) {this.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="org.zttc.itat.model">    <class name="IDCard" table="t_id_card">        <id name="id">        <!-- 表示不会自动生成,而是需要由用户来指定 -->          <!--   <generator class="assigned"/> -->        <!-- 会自动生成一个字符串,此时组件必须为String类型 -->          <generator class="native"/>        </id>        <property name="no"/>        <!-- one2one和oneToMany类似,只用增加unique=true说明只能有一个对应关系 -->        <many-to-one name="person" column="pid" unique="true"/>    </class></hibernate-mapping>

3、在hibernate.cfg.xml中添加

  <mapping resource="org/zttc/itat/model/Person.hbm.xml"/>  <mapping resource="org/zttc/itat/model/IDcard.hbm.xml"/>

4、在包org.zttc.itat.test下新建

TestOne2One.java

package org.zttc.itat.test;import org.hibernate.Session;import org.junit.Test;import org.zttc.itat.model.IDCard;import org.zttc.itat.model.Person;import org.zttc.itat.util.HibernateUtil;public class TestOne2One {@Testpublic void testAdd01() {Session session = null;try {session = HibernateUtil.openSession();session.beginTransaction();Person p = new Person();p.setName("老张");session.save(p);IDCard id = new IDCard();id.setNo("999");id.setPerson(p);session.save(id);session.getTransaction().commit();} catch (Exception e) {e.printStackTrace();if(session!=null) session.getTransaction().rollback();} finally {HibernateUtil.close(session);}}@Testpublic void testAdd02() {Session session = null;try {session = HibernateUtil.openSession();session.beginTransaction();Person p = (Person)session.load(Person.class, 2);IDCard id = new IDCard();id.setNo("333");id.setPerson(p);session.save(id);/* * 由于使用了unique,所以一个用户只能有一个IDCard,这里就会报错 */session.getTransaction().commit();} catch (Exception e) {e.printStackTrace();if(session!=null) session.getTransaction().rollback();} finally {HibernateUtil.close(session);}}}

5、运行测试函数


三、One2One双向关联项目

1、更改

Person.java

package org.zttc.itat.model;public class Person {private int id;private String name;private IDCard idCard;public IDCard getIdCard() {return idCard;}public void setIdCard(IDCard idCard) {this.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;}}

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="org.zttc.itat.model">    <class name="Person" table="t_person">        <id name="id">          <generator class="native"/>        </id>        <property name="name"/>        <!-- name表示属性的名称。property-ref表示由对端的person属性来维护关系 -->        <one-to-one name="idCard" property-ref="person"/>    </class></hibernate-mapping>

TestOne2One.java

package org.zttc.itat.test;import org.hibernate.Session;import org.junit.Test;import org.zttc.itat.model.IDCard;import org.zttc.itat.model.Person;import org.zttc.itat.util.HibernateUtil;public class TestOne2One {@Testpublic void testAdd03() {Session session = null;try {session = HibernateUtil.openSession();session.beginTransaction();/* * 此时,由于使用的是IDCard来维护关系(外键在哪一端就由哪一段来维护) * 通过p.setIdCard就无效,所以关系不会更新 */IDCard id = new IDCard();id.setNo("123");session.save(id);Person p = new Person();p.setName("zzz");p.setIdCard(id);session.save(p);session.getTransaction().commit();} catch (Exception e) {e.printStackTrace();if(session!=null) session.getTransaction().rollback();} finally {HibernateUtil.close(session);}}@Testpublic void testAdd04() {Session session = null;try {session = HibernateUtil.openSession();session.beginTransaction();Person p = new Person();p.setName("zzzzz");session.save(p);IDCard id = new IDCard();id.setNo("12322");id.setPerson(p);session.save(id);session.getTransaction().commit();} catch (Exception e) {e.printStackTrace();if(session!=null) session.getTransaction().rollback();} finally {HibernateUtil.close(session);}}@Testpublic void testLoad01() {Session session = null;try {session = HibernateUtil.openSession();session.beginTransaction();Person p = (Person)session.load(Person.class, 4);//只要取出的是没有维护关系的这一方,会自动将关联对象取出,会发出1条sql//由于person端没有维护关系,所以不会进行延迟加载,所以1条就搞定了System.out.println(p.getName()+","+p.getIdCard().getNo());session.getTransaction().commit();} catch (Exception e) {e.printStackTrace();if(session!=null) session.getTransaction().rollback();} finally {HibernateUtil.close(session);}}@Testpublic void testLoad02() {Session session = null;try {session = HibernateUtil.openSession();session.beginTransaction();//特别注意:如果没有双向,此时会发出2条,一条去idCard,一条延迟加载取person//此时会发出三条SQL语句IDCard id = (IDCard)session.load(IDCard.class, 4);//此时没有使用idCard的Person,会延迟加载,目前只是发出1条SQLSystem.out.println(id.getNo());//要去取person同时也会取出这个person的idCard,这里就不会使用join来取出,所以会发出2条sqlSystem.out.println(id.getPerson().getName());session.getTransaction().commit();} catch (Exception e) {e.printStackTrace();if(session!=null) session.getTransaction().rollback();} finally {HibernateUtil.close(session);}}/** * 最佳实践就是,One2One的时候最好不要使用双向关联,如果使用双向关联,尽可能在没有维护关系的一边取数据 * hibernate会自动完成joine,仅仅只会发一条sql,如果使用维护关系端取数据,在通过延迟加载取关联对象时 * 会同时再去取person的idCard关联,所以会发3条 */}