现在的位置: 首页 > 综合 > 正文

Hibernate一对一外键关联映射(双向)

2018年06月05日 ⁄ 综合 ⁄ 共 3242字 ⁄ 字号 评论关闭

Hibernate一对一唯一外键关联映射(双向关联Person<——>IDCard)。

类图:

映射的数据库表:

Person.java:

public class Person {

	private Integer id;
	private String name;

	/*定义Person和IDCard的关系(双向一对一唯一外键关联)*/
	private IDCard idCard;
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public IDCard getIdCard() {
		return idCard;
	}

	public void setIdCard(IDCard idCard) {
		this.idCard = idCard;
	}

	
}

注:因为是双向一对一唯一外键关联,所以Person中有IDCard的引用,IDCard中也有Person的引用。

IDCard.java:

public class IDCard {

	private Integer id;
	private String cardNo;
	/* IDCard和Person的关系(双向一对一唯一外键关联) */
	private Person person;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getCardNo() {
		return cardNo;
	}

	public void setCardNo(String cardNo) {
		this.cardNo = cardNo;
	}

	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}

}

注:因为是一对一唯一外键关联,所以IDCard中有Person的引用,Person中也有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="com.lixue.bean">
	<class name="Person" table="t_person">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<!-- 
			一对一唯一外键关联映射其实是多对一的特例,我们使用many-to-one
			但是指定多的一端unique为true,这样就限制了多的一端的多重性
		 -->
		<many-to-one name="idCard" unique="true"/>
	</class>
</hibernate-mapping>

注:一对一唯一外键关联映射其实是多对一的特例,我们使用many-to-one来映射,但是指定多的一端unique为true,这样就限制了多的一端的多重性。

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="com.lixue.bean">
	<class name="IDCard" table="t_idCard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
		<!-- 映射一对一关联 property-ref表示要引用的属性为idCard-->
		<one-to-one name="person" property-ref="idCard"/>
	</class>
</hibernate-mapping>

注:在IDcard这一段也要指定one-to-one映射。


测试方法:

public void testSave1(){
		/*定义Session和事物*/
		Session session = null;
		Transaction transaction = null;
		
		try {
			/*获取Session并开启事物*/
			session = HibernateUtils.getSession();
			transaction = session.beginTransaction();
			
			/*创建身份证并设置属性*/
			IDCard idCard = new IDCard();
			idCard.setCardNo("367578677545348879");
			
			/*创建人并设置属性*/
			Person person = new Person();
			person.setName("习近平");
			/*建立关联*/
			person.setIdCard(idCard);
			
			/**
			 * 会抛出TransientObjectException异常
			 * 因为IDCard对象此时为Transient对象,数据库中
			 * 没有与之对应的数据导致出错
			 */
			session.save(person);
			/*提交事物*/
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
			transaction.rollback();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}

注:抛异常的原因是因为IDCard对象此时还是Transient状态,数据库中没有与之对应的数据。

测试方法二:

public void testSave3(){
		/*定义Session和事物*/
		Session session = null;
		Transaction transaction = null;
		
		try {
			/*获取Session并开启事物*/
			session = HibernateUtils.getSession();
			transaction = session.beginTransaction();
			
			/*创建身份证并设置属性*/
			IDCard idCard = new IDCard();
			idCard.setCardNo("367578677545348879");
			
			/*创建人并设置属性*/
			Person person = new Person();
			person.setName("习近平");
			/*建立关联*/
			person.setIdCard(idCard);
			
			/**
			 * 不会抛出TransientObjectException异常
			 * 因为我们显示的调用了save方法使得IDCard对象变为Persistent对象,数据库中
			 * 有与之对应的数据
			 */
			session.save(idCard);
			session.save(person);
			/*提交事物*/
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
			transaction.rollback();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
	

注:这样可以保存成功,因为我们显示的保存了IDCard对象,使IDCard对象由Transient对象变为Persistent状态。

抱歉!评论已关闭.