one-to-one 一对一主键关联映射_单向
one-to-one 一对一主键关联映射_单向
一对一主键关联映射——关联的两个实体共享一个主键(让两个实体对象的id保持相同),这样可以避免多余的字段被创建 .
(单向关联Person---->IdCard)
类:
public class IdCard {
private Integer id;
private String idNo;
}
public class Person {
private Integer id;
private String name;
private IdCard idCard;
}
hbm.xml
IdCard.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.model">
<class name="IdCard" table="idcard1" >
<id name="id" column="id" type="java.lang.Integer">
<generator />
</id>
<property name="idNo" column="id_no" type="java.lang.String" />
</class>
</hibernate-mapping>
Person.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zd.model">
<class name="Person" table="person1" >
<id name="id" column="id" type="java.lang.Integer">
<!-- person的主键来源idCard,也就是共享idCard的主键 -->
<generator column="name" length="50" type="java.lang.String" />
<one-to-one name="idCard" ></one-to-one>
<!--one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,
one-to-one的属性cascade=all ,即新增Person时,同时可新增idcard,
constrained="true", 表明当前主键上存在一个约束,person的主键作为外键参照了idCard
<one-to-one name="idCard" constrained="true"></one-to-one>
-->
</class>
</hibernate-mapping>
运用例子:
public void testSave1(){
Session session = null;
Transaction ta = null;
try{
session = HibernateUtil.getSession();
ta = session.beginTransaction();
IdCard idCard = new IdCard();
idCard.setIdNo("88888888888888");
Person p = new Person();
p.setName("Tom");
p.setIdCard(idCard);
//session.save(idCard); //可删除,因one-to-one 默认casedese=all
session.save(p); // 保存idCard, person2个。
ta.commit();
}catch(Exception e){
e.printStackTrace();
if(ta != null){
ta.rollback();
}
}finally{
//关闭session, user变为detached离线对象
HibernateUtil.closeSession(session);
}
}
Hibernate: insert into idcard1 (id_no) values (?)
Hibernate: insert into person1 (name, id) values (?, ?)
public void testGet1(){
Session session = null;
Transaction ta = null;
try{
session = HibernateUtil.getSession();
ta = session.beginTransaction();
Person p = (Person) session.get(Person.class, new Integer(2));
System.out.println("person.name=" + p.getName());
System.out.println("idCard.cardNo=" + p.getIdCard().getIdNo());
ta.commit();
}catch(Exception e){
e.printStackTrace();
if(ta != null){
ta.rollback();
}
}finally{
//关闭session, user变为detached离线对象
HibernateUtil.closeSession(session);
}
}
Hibernate: select person0_.id as id1_0_, person0_.name as name1_0_ from person1 person0_ where person0_.id=?
person.name=Tom
Hibernate: select idcard0_.id as id0_0_, idcard0_.id_no as id2_0_0_ from idcard1 idcard0_ where idcard0_.id=?
idCard.cardNo=88888888888888
===================================================================
戓要改为双向,修改以下:
public class IdCard {
private Integer id;
private String idNo;
private Person person; //加个对象变量
}
IdCard.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zd.model">
<class name="IdCard" table="idcard1" >
<id name="id" column="id" type="java.lang.Integer">
<generator />
</id>
<property name="idNo" column="id_no" type="java.lang.String" />
<one-to-one name="person"></one-to-one>
</class>
</hibernate-mapping>
测试用例:
public void testGet2(){
Session session = null;
Transaction ta = null;
try{
session = HibernateUtil.getSession();
ta = session.beginTransaction();
IdCard ic = (IdCard)session.get(IdCard.class, new Integer(1));
System.out.println("IdCard.idNo =" + ic.getIdNo());
System.out.println("Person.name = " + ic.getPerson().getName());
ta.commit();
}catch(Exception e){
e.printStackTrace();
if(ta != null){
ta.rollback();
}
}finally{
//关闭session, user变为detached离线对象
HibernateUtil.closeSession(session);
}
}
执行一条sql语句,且是join, 因为one-to-one默认是fetch="join"
Hibernate: select idcard0_.id as id0_1_, idcard0_.id_no as id2_0_1_, person1_.id as id1_0_, person1_.name as name1_0_ from idcard1 idcard0_ left outer join person1 person1_ on idcard0_.id=person1_.id where idcard0_.id=?
IdCard.idNo =88888888888888
Person.name = Tom
若IdCard.hbm.xml 中<one-to-one name="person" fetch="select"></one-to-one> ,执行2条sql
Hibernate: select idcard0_.id as id0_0_, idcard0_.id_no as id2_0_0_ from idcard1 idcard0_ where idcard0_.id=?
Hibernate: select person0_.id as id1_0_, person0_.name as name1_0_ from person1 person0_ where person0_.id=?
IdCard.idNo =88888888888888
Person.name = Tom
================================
fetch取值"select",表示序列选择抓取,还有一个值是"join",表示采用外连接抓取。