Hibernate基于配置文件(十二)一对一双向关联映射

一对一关联关系,当需要对2个对象进行独立对待时,分2个类来完成映射

 

主键关联映射,没有额外字段维护关联,id值保持一致

package org.leadfar.hibernate.model;


public class Person {
	private long id;
	private String name;
	private IdCard idcard;
	
	Person(){}
	
	public long getId() {
		return id;
	}
	public IdCard getIdcard() {
		return idcard;
	}

	public String getName() {
		return name;
	}
	public void setId(long id) {
		this.id = id;
	}
	public void setIdcard(IdCard idcard) {
		this.idcard = idcard;
	}
	public void setName(String name) {
		this.name = name;
	}

	
}

 

<?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.hibernate.auction">
	<class name="org.leadfar.hibernate.model.Person" table="t_persons" >
		<!-- id为数据库标识,作为主键 -->
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<!-- 根据本方id到t_idcard中寻找id值相同的那条记录 -->
		<one-to-one name="idcard"> </one-to-one>
		
	</class>
	
</hibernate-mapping>

 

package org.leadfar.hibernate.model;


public class IdCard {
	private long id;
	private String sn;
    private Person person;
    
    IdCard() {}
	public long getId() {
		return id;
	}
	public Person getPerson() {
		return person;
	}
	
	
	public String getSn() {
		return sn;
	}
	public void setId(long id) {
		this.id = id;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	public void setSn(String sn) {
		this.sn = sn;
	}

}

 

<?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.hibernate.auction">
	<class name="org.leadfar.hibernate.model.IdCard" table="t_idcard" >
		
		<id name="id">
			<!-- 使用foreign表示本记录的id值依赖于对方的id值 -->
			<generator class="foreign">
			<!-- 表示被依赖的对象(通过对象可以映射到表中某条记录,从而得到id) -->
			<param name="property">person</param>
			</generator>
		</id>
		<property name="sn" not-null="true" unique="true"></property>
		<!--constraint表示外键具有约束条件,即idcard存在时不能删除对应的person -->
		<!-- one-to-one表示根据自己的id到对方表中寻找相同id值的记录 -->
		<one-to-one name="person" constrained="true"></one-to-one>
		
	</class>
	
</hibernate-mapping>

 

测试

package org.leadfar.hibernate.model;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import junit.framework.TestCase;

public class OneToOneTest extends TestCase {
	
	public void oneToOne_save() {
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.openSession();
		
		try {
			session.beginTransaction();
			/**
			 *配置文件映射方式:one-to-one idCard的id生成策略为foreign,参考Person的id属性来设置自己的id(两者id保存一致)
			 *先有Person,再有IdCard,其中IdCard的id属性生成需要参考Person中的id
			 *所以,必需先保存Person,再保存IdCard
			 */
			
			Person p1 = new Person();
			p1.setName("张三1");
			Person p2 = new Person();
			p2.setName("张三2");
			Person p3 = new Person();
			p3.setName("张三3");
			session.save(p1);
			session.save(p2);
			session.save(p3);
			
			
			IdCard idcard = new IdCard();
			idcard.setSn("21938404320997903");
			idcard.setPerson(p3);//通过p3找到数据库中对应的id,然后作为idcard记录的id
			
			session.save(idcard);
			
			
			session.getTransaction().commit();
		} catch(Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	
	//根据Person获取idCard
	public void oneToOne_load01() {
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.openSession();
		
		try {
			session.beginTransaction();
			
			Person p1 = (Person)session.load(Person.class, 3L);//如果id为long类型,则需要加L后缀
			IdCard idcard = p1.getIdcard();
			System.out.println(p1.getName()+","+idcard.getSn());
			
			session.getTransaction().commit();
		} catch(Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	//根据idCard获取Person
	public void oneToOne_load02() {
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.openSession();
		
		try {
			session.beginTransaction();
			
			IdCard idcard = (IdCard)session.load(IdCard.class, 3L);
			Person person = idcard.getPerson();
			System.out.println(idcard.getSn()+","+person.getName());
			
			session.getTransaction().commit();
		} catch(Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
}

 

 

唯一外键关联映射,在其中一端使用1个字段记录对方的id

package org.leadfar.hibernate.model;


public class Person {
	private long id;
	private String name;
	private IdCard idcard;
	
	Person(){}
	
	public long getId() {
		return id;
	}
	public IdCard getIdcard() {
		return idcard;
	}

	public String getName() {
		return name;
	}
	public void setId(long id) {
		this.id = id;
	}
	public void setIdcard(IdCard idcard) {
		this.idcard = idcard;
	}
	public void setName(String name) {
		this.name = name;
	}

	
}

 

<?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.hibernate.auction">
	<class name="org.leadfar.hibernate.model.Person" table="t_persons" >
		<!-- 外键关联时,id生成策略任意皆可,因为不是通过id进行关联的 -->
		<id name="id">
			<generator class="assigned">
			</generator>
		</id>
		<property name="name"/>
		<!-- property-ref="person"说明映射的时候将参考对方的person属性字段来映射,而不是通过对方的主键id来映射的!-->
		<!-- 如果不指定property-ref="person" 将会根据对方的id主键进行映射,就不是通过外键来映射了!一定要搞清楚!!-->
		<one-to-one name="idcard" property-ref="person"> </one-to-one>
		
	</class>
	
</hibernate-mapping>

 

package org.leadfar.hibernate.model;


public class IdCard {
	private long id;
	private String sn;
    private Person person;
    
    IdCard() {}
	public long getId() {
		return id;
	}
	public Person getPerson() {
		return person;
	}
	
	
	public String getSn() {
		return sn;
	}
	public void setId(long id) {
		this.id = id;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	public void setSn(String sn) {
		this.sn = sn;
	}

}

 

<?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.hibernate.auction">
	<class name="org.leadfar.hibernate.model.IdCard" table="t_idcard" >
		<!-- 外键关联时,id生成策略任意皆可,因为不是通过id进行关联的 -->
		<id name="id">
			<generator class="assigned"/>
		</id>
		<property name="sn" not-null="true" unique="true"></property>
		<!-- unique=true 将many-to-one 限制为一对一关系 -->
		<!-- 外键将使用many-to-one中的属性,即person属性将作为外键被使用 -->
		<!-- 也就是说,IdCard一端将通过person属性去获取Person -->
		<!-- 而且,Person一端如果要使用person字段映射到本表的话,就必须使用property-ref=person -->
		<!-- 这样双方才能通过唯一的person进行双向关联映射 -->
		<many-to-one name="person" unique="true" column="personid"></many-to-one>
		
	</class>
	
</hibernate-mapping>

 

测试

package org.leadfar.hibernate.model;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import junit.framework.TestCase;

public class OneToOneTest extends TestCase {
	public void oneToOne_save() {
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.openSession();
		
		try {
			session.beginTransaction();
			/**
			 *one-to-one 外键关联映射 
			 *1.先保存Person (one-to-one)Idcard中的person字段值需要参考person表的主键id
			 *<one-to-one name="idcard" property-ref="person"> </one-to-one>
			 *
			 *2.再保存IdCard,其中IdCard中的person属性将使用前面保存的Person对象 (many-to-one)
			 *<many-to-one name="person" unique="true" column="personid"></many-to-one>
			 */
			
			Person p1= new Person();
			p1.setId(1L);
			p1.setName("1abc");
			session.save(p1);
			
			Person p2= new Person();
			p2.setId(2L);
			p2.setName("2abc");
			session.save(p2);
			
			Person p3= new Person();
			p3.setId(3L);
			p3.setName("3abc");
			session.save(p3);
			
			
			IdCard idcard1 = new IdCard();
			idcard1.setId(2L);
			idcard1.setSn("11111111111");
			idcard1.setPerson(p1);//关联关系一定不要丢
			session.save(idcard1);
			
			IdCard idcard2 = new IdCard();
			idcard2.setId(3L);
			idcard2.setSn("22222222222");
			idcard2.setPerson(p2);//关联关系一定不要丢
			session.save(idcard2);
			
			IdCard idcard3 = new IdCard();
			idcard3.setId(4L);
			idcard3.setSn("33333333333");
			idcard3.setPerson(p3);//关联关系一定不要丢
			session.save(idcard3);
			
			session.getTransaction().commit();
		} catch(Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	
	//根据Person获取idCard
	public void oneToOne_load01() {
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.openSession();
		
		try {
			session.beginTransaction();
			
			Person p1 = (Person)session.load(Person.class, 2L);//如果id为long类型,则需要加L后缀
			IdCard idcard = p1.getIdcard();
			System.out.println(p1.getName()+","+idcard.getSn());
			
			session.getTransaction().commit();
		} catch(Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	//根据idCard获取Person
	public void oneToOne_load02() {
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.openSession();
		
		try {
			session.beginTransaction();
			
			IdCard idcard = (IdCard)session.load(IdCard.class, 2L);
			Person person = idcard.getPerson();
			System.out.println(idcard.getSn()+","+person.getName());
			
			session.getTransaction().commit();
		} catch(Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
}

 

 

 

你可能感兴趣的:(Hibernate)