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


一、一对一关系


二、一对一单向关联项目

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 {
	@Test
	public 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);
		}
	}
	
	
	@Test
	public 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 {
	@Test
	public 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);
		}
	}
	
	@Test
	public 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);
		}
	}
	
	@Test
	public 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);
		}
	}
	
	@Test
	public 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条SQL
			System.out.println(id.getNo());
			//要去取person同时也会取出这个person的idCard,这里就不会使用join来取出,所以会发出2条sql
			System.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条
	 */
	
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值