hibernate (三) OneToOne_xml(单向和双向关联)

(1) 单向关联

实体类:Person.java   IDCard.java

public class IDCard {
   
	private int id;
	private String no;
	private Person person;
   省略get,set
}

public class Person {
     
	private int id;
	private String name;
    省略get,set	
}

   IDCard.hbm.xml,Person.hbm.xml

 

<hibernate-mapping package="org.th.model">
    <class name="IDCard" table="t_idcard" >
        <id name="id">
           <generator class="native"></generator>
        </id>
        <property name="no"></property>
        <many-to-one name="person" column="pid" unique="true"></many-to-one>
     </class>
</hibernate-mapping>

<hibernate-mapping package="org.th.model">
    <class name="Person" table="t_person" >
        <id name="id">
           <generator class="native"></generator>
        </id>
        <property name="name"></property>
     </class>
</hibernate-mapping>

  (2) 双向关联

public class IDCard {
   
	private int id;
	private String no;
	private Person person;
   省略get,set
}

public class Person {
     
	private int id;
	private String name;
     private IDCard idcard;//相对单向加一个属性
    省略get,set	
}

 

IDCard.hbm.xml,Person.hbm.xml 

<hibernate-mapping package="org.th.model">
    <class name="IDCard" table="t_idcard" >
        <id name="id">
           <generator class="native"></generator>
        </id>
        <property name="no"></property>
        <many-to-one name="person" column="pid" unique="true"></many-to-one>
     </class>
</hibernate-mapping>

<hibernate-mapping package="org.th.model">
    <class name="Person" table="t_person" >
        <id name="id">
           <generator class="native"></generator>
        </id>
        <property name="name"></property>
        <!--name是属性名称,property-ref表示由对方的属性来维护关系,当然配置文件反过来写
          也是可以的 -->
        <one-to-one name="idcard" property-ref="person" ></one-to-one>
     </class>
</hibernate-mapping>

  测试类 TestOneToOne.java :

public class TestOneToOne {
	@Test
	public void testAdd01() {
		Session session = null;
		try {
			session = HibernateUtil.openSession();
			session.beginTransaction();

			Person person = new Person();
			person.setName("老张");
			session.save(person);

			IDCard idcard = new IDCard();
			idcard.setNo("999");
			idcard.setPerson(person);
			session.save(idcard);

			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			if (session != null)
				session.getTransaction().rollback();
		} finally {
			if (session != null)
				HibernateUtil.close(session);
		}
	}

	@Test
	public void testAdd02() {
		Session session = null;
		try {
			session = HibernateUtil.openSession();
			session.beginTransaction();

			Person person = (Person) session.load(Person.class, 1);

			// ConstraintViolationException: Duplicate entry '1' for key 2
			// Many-to-one 当使用了unique=true,就会保证每一个person只能对应一个idcard
			IDCard idcard = new IDCard();
			idcard.setNo("111");
			idcard.setPerson(person);
			session.save(idcard);

			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			if (session != null)
				session.getTransaction().rollback();
		} finally {
			if (session != null)
				HibernateUtil.close(session);
		}
	}

	/**
	 * 
	 * @Title: testAdd03
	 * @Description: oneToOne 双向关联
	 * @param
	 * @return void 返回类型
	 * @throws
	 */
	@Test
	public void testAdd03() {
		Session session = null;
		try {
			session = HibernateUtil.openSession();
			session.beginTransaction();

			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			if (session != null)
				session.getTransaction().rollback();
		} finally {
			if (session != null)
				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条
	 */

 

 

 

你可能感兴趣的:(Hibernate)