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

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

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

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

一对一唯一外键关联映射其实是多对一的特例,采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一。

类图:

映射的数据库表:

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,所以在Person中应该有IDCard的引用。

IDCard.java:

public class IDCard {

	private Integer id;
	private String cardNo;
	
	
	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;
	}


}

注:因为是单向一对一关联,且从Person可以关联到IDCard但是从IDCard不能关联到Person,所以在IDCard中没有Person的引用。

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"/>
	</class>
</hibernate-mapping>

注:IDCard一端是普通的javaBean,所以值是普通的属性映射。

测试通过Person添加IDCard:

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为瞬时状态的对象,所以不能级联保存。

测试二:

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对象时,我们就可以使其变为Persistent状态,从而两个对象都可以保存成功。

抱歉!评论已关闭.