hibernate 学习之第六篇

关键字: hibernate 一对一 关联

基于主键的一对一关联

Person类和IdCard,一对一映射。
person的属性为:id,name,idCard
IdCard的属性为:id,usefulLife,person

由于身份证和人是一对一的,身份证的id和人的id可以相同。可以使得idcard的id的产生与person保持一致。主从对象通过主键关联起来。

类Person:

Java代码
  1. public class Person {   
  2. private int id;   
  3. private String name;   
  4. private IdCard idCard;   
  5.     public int getId() {   
  6.         return id;   
  7.     }   
  8.   
  9.     public void setId(int id) {   
  10.         this.id = id;   
  11.     }   
  12.   
  13.     public IdCard getIdCard() {   
  14.         return idCard;   
  15.     }   
  16.   
  17.     public void setIdCard(IdCard idCard) {   
  18.         this.idCard = idCard;   
  19.     }   
  20.   
  21.     public String getName() {   
  22.         return name;   
  23.     }   
  24.   
  25.     public void setName(String name) {   
  26.         this.name = name;   
  27.     }   
  28.   
  29. }  

 

类IdCard:

Java代码
  1. public class IdCard {   
  2. private int id;   
  3. private Date usefulLife;   
  4. private Person person;   
  5.     public int getId() {   
  6.         return id;   
  7.     }   
  8.   
  9.     public void setId(int id) {   
  10.         this.id = id;   
  11.     }   
  12.   
  13.     public Person getPerson() {   
  14.         return person;   
  15.     }   
  16.   
  17.     public void setPerson(Person person) {   
  18.         this.person = person;   
  19.     }   
  20.   
  21.     public Date getUsefulLife() {   
  22.         return usefulLife;   
  23.     }   
  24.   
  25.     public void setUsefulLife(Date usefulLife) {   
  26.         this.usefulLife = usefulLife;   
  27.     }   
  28.   
  29. }  

 

映射文件person.hbm.xml

 

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  3. <hibernate-mapping package="hibernatetest01">  
  4.     <class name="Person" table="t_person">  
  5.         <id name="id" >  
  6.             <generator class="native"></generator>  
  7.         </id>  
  8.         <property name="name"></property>  
  9.        <one-to-one name="idCard"/>   //person和idcard是一对一映射   
  10.     </class>  
  11. </hibernate-mapping>  

 

映射文件idcard.hbm.xml

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  3. <hibernate-mapping package="hibernatetest01">  
  4.     <class name="IdCard" table="t_idcard">  
  5.         <id name="id" >  
  6.             <generator class="foreign">       
  7.                 <param name="property">person</param>  
  8.             </generator>  
  9.         </id>  
  10.         <property name="usefulLife"></property>  
  11.        <one-to-one name="person"  constrained="true"/> //加上约束,保证了person必须有idcard与之对应,未加时,保存person可以没有idcard   
  12.     </class>  
  13. </hibernate-mapping>  

 

注: 采用外键产生方式,该类有一个属性参数,需要在配置文件中指定给他,他需要知道利用什么来产生idcard的主键。在此指定person,与下面的 <one-to-one name="person"/>对应。

测试类:

Java代码
  1. public class Main {   
  2.     public static void main(String[] args){   
  3.     add();   
  4.     }   
  5.   
  6.     static Person add(){   
  7.         IdCard idCard = new IdCard();   
  8.         idCard.setUsefulLife(new Date());   
  9.         Person  p = new Person();   
  10.         p.setName("jianchen");   
  11.         p.setIdCard(idCard);   
  12.         idCard.setPerson(p);   
  13.         Session s = null;   
  14.         Transaction tx = null;   
  15.         s = HibernateUtil.getSession();   
  16.         tx = s.beginTransaction();   
  17.         s.save(p);   
  18.          s.save(idCard);   
  19.         tx.commit();   
  20.        return p;   
  21.     }   
  22. }  

 


一对一主键关联关系的检索:

Java代码
  1. static void query(int id){   
  2.     Session s = HibernateUtil.getSession();   
  3.     Transaction tx = s.beginTransaction();   
  4.     Person p = (Person)s.get(Person.class, id);   
  5.     System.out.println(p.getIdCard().getUsefulLife());   
  6.     tx.commit();   
  7.    }  

 


在主函数中调用query(1),person和idcard是主从关系。对主类进行查询,会把从类也查询出来,体现在查询使用左外连接,一次性的查询。

Hibernate: select person0_.id as id1_1_, person0_.name as name1_1_, idcard1_.id as id2_0_, idcard1_.usefulLife as usefulLife2_0_ from t_person person0_ left outer join t_idcard idcard1_ on person0_.id=idcard1_.id where person0_.id=?
2009-02-04 15:51:20.0

 

就是把打印的那句话注释掉,同样会一次性的查出主从类 。查询语句如下:

 

Hibernate: select person0_.id as id1_1_, person0_.name as name1_1_, idcard1_.id as id2_0_, idcard1_.usefulLife as usefulLife2_0_ from t_person person0_ left outer join t_idcard idcard1_ on person0_.id=idcard1_.id where person0_.id=?

 

如果是查询从类,

Java代码
  1. static void query(int id){   
  2.      Session s = HibernateUtil.getSession();   
  3.      Transaction tx = s.beginTransaction();   
  4.      IdCard idCard =(IdCard) s.get(IdCard.class, id);   
  5.      System.out.println(idCard.getPerson().getName());   
  6.      tx.commit();   
  7.     }  
 


对从类进行查询只会查询出从类的信息,主类被懒加载。从查询语句上看,以上代码执行了两次查询。

Hibernate: select idcard0_.id as id2_0_, idcard0_.usefulLife as usefulLife2_0_ from t_idcard idcard0_ where idcard0_.id=?
Hibernate: select person0_.id as id1_1_, person0_.name as name1_1_, idcard1_.id as id2_0_, idcard1_.usefulLife as usefulLife2_0_ from t_person person0_ left outer join t_idcard idcard1_ on person0_.id=idcard1_.id where person0_.id=?
jianchen
 

把后面的打印语句删掉,就只会执行上面的一次查询。

Hibernate: select idcard0_.id as id2_0_, idcard0_.usefulLife as usefulLife2_0_ from t_idcard idcard0_ where idcard0_.id=?

 


使用lazy属性:
修改映射文件:

Xml代码
  1. <hibernate-mapping package="hibernatetest01">  
  2.     <class name="IdCard" table="t_idcard">  
  3.         <id name="id" >  
  4.             <generator class="foreign">       
  5.                 <param name="property">person</param>  
  6.             </generator>  
  7.         </id>  
  8.         <property name="usefulLife"></property>  
  9.        <one-to-one name="person"  constrained="true" lazy="false"/> //加上约束,保证了person必须有idcard与之对应,未加时,保存person可以没有idcard   
  10.     </class>  
  11. </hibernate-mapping>  

 

分析:
lazy=”false“表明对person不进行懒加载。这样就会导致在查询从类时也会把主类进行加载。
lazy在hibernate 3.0之前只有两个值:true ,false
3.0后lazy有三个值:true,false,proxy。其中proxy是默认的方式,采用代理实现懒加载。


在以上基础上进行进一步的修改:
 <one-to-one name="person"  constrained="true" lazy="true" fetch="select" />
虽然配置为懒加载,但由于设置了抓取为select ,就是说在抓取idcard时,也会抓取person。这也会导致在加载从对象时即时的加载主对象。

由此可见,hibernate中的属性配置是互相制约和影响的。hibernate的难点也在此。

基于外键的一对一关联

可以描述为多对一,加uniquer=“ture”,就变为一对一关联了
对象模型不需要改变,对映射文件进行修改。
person.hbm.xml文件:

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  3. <hibernate-mapping package="hibernatetest01">  
  4.     <class name="Person" table="t_person">  
  5.         <id name="id" >  
  6.             <generator class="native"></generator>  
  7.         </id>  
  8.         <property name="name"></property>  
  9.        <one-to-one name="idCard" property-ref="person"/>   //person通过idcard的属性person来查找属于自己的idcard   
  10.     </class>  
  11. </hibernate-mapping>  
 


注:  property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。

idcard.hbm.xml映射文件:

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  3. <hibernate-mapping package="hibernatetest01">  
  4.     <class name="IdCard" table="t_idcard">  
  5.         <id name="id" >  
  6.             <generator class="native"></generator>  
  7.         </id>  
  8.         <property name="usefulLife"></property>  
  9.        <many-to-one name="person"  column="person_id" unique="true"/>  
  10.     </class>  
  11. </hibernate-mapping>  

 

表结构为:


从这个表结构上看,person和idcard是一对多的关系,因为idcard表有一个外键指向person表。但是在idcard的映射文件中,把外键强制设定为唯一,这样就构成了一对一映射。
  <many-to-one name="person"  column="person_id" unique="true"/>

你可能感兴趣的:(Hibernate,String,table,Class,generator,encoding)