*一对一主键关联:单向:Person这一端看的!!!!!
Person引用了IdCard,所有IdCard必须先有值
主键关联:t_person中主键不是自己生成的,引用t_idcard的!!所以要持有IdCard的引用
实体类:
class IdCard:
private int id;
private String cardNo;
class Person:
private int id;
private String name;
private IdCard idCard;//使这两个pojo关联起来
映射文件:
IdCard:
<hibernate-mapping>
<class name="com.guojie.hibernate.IdCard" table="t_idcard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
Person:
<class name="com.guojie.hibernate.Person" table="t_person">
<id name="id">
<generator class="foreign">
<!—name=”propertye”固定,表明主键来源于IdCard的主键,idCard找到Person中的属性IdCard,再找到IdCard的标识 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!-- idCard表示:外键 -->
<!—加载Person的时候,IdCard找到Person的主键,然后把IdCard加载进来(默认根据主键加载),放到Person的idCard属性中-->
<!--constrained="true":表明Person的主键还是外键,参考至IdCard的主键--> 去掉constrained="true" 程序load、save正常,为什么???
<one-to-one name="idCard" constrained="true"/>
</class>
测试代码:
public void testSave1(){
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
IdCard idCard = new IdCard();
idCard.setCardNo("8888888");
Person person = new Person();
person.setName("菜10");
person.setIdCard(idCard);
//在保存person的时候自动保存IdCard
//只有一对一主键关联中默认实现了cascade属性,保存person的自动先把IdCard保存了
//把IdCard中的主键取来当作person中的主键
session.save(person);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
public void testLoad1(){
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
Person person = (Person)session.load(Person.class, 1);
System.out.println(person.getName());
System.out.println(person.getIdCard().getCardNo());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
*一对一单向关联(Person-->IdCard)
*一对一主键关联映射:让两个实体对应的id保持相同,这样可以避免多于字段被创建
*具体映射:
<id name="id">
<generator class="foreign">
<!--person的主键来源idCard,person中的主键从idCard中找的!!共享idCard的主键-->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!--one-to-one:指示hibernate怎么加载它的关联对象,默认根据主键->
<!--constrained="true":表明当前的主键还是外键,加入了外键约束-->
<one-to-one name="idCard" constrained="true"/>
*以上例子:只能Person端加载IdCard端,IdCard端无法加载Person端
加入IdCard端加载Person端,变成了双向,从两端都可以加载,例子:
则实体类IdCard中要持有Person的引用,Person类要持有IdCard的引用
private int id;
private String cardNo;
private Person person;
IdCard的映射:
<class name="com.guojie.hibernate.IdCard" table="t_idcard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="cardNo"/>
<!-- constrained="true" :根据人的id加载IdCard -->
<one-to-one name="person" constrained="true">
</one-to-one>
</class>
Person的映射:
<class name="com.guojie.hibernate.Person" table="t_person">
<id name="id">
<generator class="foreign">
<!-- name:固定 idCard是Person中的外键,表示参考至IdCard -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!-- idCard表示:外键 -->
<!-- true:根据主键加载关联对象 -->
<!--constrained="true":人的id来自身份证的id,不能与IdCard中同时配这个属性-->
<one-to-one name="idCard" />
</class>
!!两边同时去掉constrained="true">也能正确加载!!!???
Person端加载例子:也可以IdCard端加载
public void testLoad1(){
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
Person person = (Person)session.load(Person.class,1);
System.out.println(person.getName());
System.out.println(person.getIdCard().getCardNo());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}