Hibernate一对一外键关联双向/单向映射

一对一外键关联单向映射

  一对一的关联依然可以使用学生-学号的关系来描述。而所谓的外键关联,就是没张表都有自己独立的ID,各自的ID并不参照其它表的ID来生成。想要通过学 生表获得学生学号,依然需要在学生表持有学号表的引用,不同的是,在学生表中,独立的创建一个列用来记录于学号表的对应关系。

        Student表                                                    StudentNumber表

+-------------------------------------------+             +---------------------------+

  ID     |    StudentName    |   key                      ID   | StudentNumber

  从上面的描述看,student表的“key”用来参照studentNumber的ID来生成,而多个key可以对应一个学号表的ID。出现了多对一的 情况,不同的是,我们给key设置为唯一性为true。用来使key不重复。就可以保证一对一的独立性。由此看来,一对一外键关联映射其实是多对一的一个 特例而已。


开始创建实例

  依然使用student对象,提供private String id;private String name;private StudentNumber studentnumber;//持有studentNumber引用,提供对应Get/Set方法。

student.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>      
<class name="com.java50.www.hibernate.Student">          
<id name="id">       
 <generator class="uuid" />    </id>       
<property name="name" />          
<many-to-one name="studentnumber" unique="true" /> 
 </class>  
</hibernate-mapping>  

注:为了演示更加明显。我将student的ID设置为UUID。即,数字字母字符串序列。


StudentNumber,提供private int id;private String number;和对应Get/Set方法


StudentNumber.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>      
<class name="com.java50.www.hibernate.StudentNumber" >          
<id name="id">       
 <generator class="native" />         
 </id>          
<property name="number" unique="true" />      
</class>  
</hibernate-mapping>  

注:这里的ID设置为native,让其ID自增。


测试方案:

  从数据库表的关系可以看的出,为student表新建一个外键,该外键是唯一的,并且参照了studentnumber的ID值

 student表列的关系



student的外键参照了studentnumber的ID值

一对一外键关联双向映射

  和单向映射不同的是,单向映射只能通过student对象获取学生的姓名和对应的学号,因为在student对象中持有了studentnumber的引用。


想要实现双向映射,那么StudentNumber也应当持有Student对象的引用。


  所以StudentNumber拥有属性int id;int number;Student student;//Student的引用。

 配置文件StudentNumber.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>      
<class name="com.java50.www.hibernate.StudentNumber" >          
<id name="id">              
<generator class="native" />         
 </id>          
<property name="number" unique="true" />          
<one-to-one name="student" property-ref="studentnumber" />     
 </class>  
</hibernate-mapping>  

注:这里需要强调的是<one-to-one>标签。这 里使用了property-ref属性,如果不设置的话,当studentNumber拿到student的引用时,studentNumber的ID默 认是和student的主键来比较的,这显然不对,我们需要和student的外键studentnumber来比较才是目的。通过property- ref设置比对的列名。


测试方案:

  写一个TestGet()方法来测试双向读取数据。

public void testGet(){          
  Session session = null;          
try{              
  session = HibernateUnit.getSession();      
  session.beginTransaction();       
  Student student=(Student)session.load(Student.class,"2c9cca83363a6dcb01363a6dccdc0001");    
  System.out.println("使用student对象获取学生信息");       
  System.out.println("student-name="+student.getName());     
  System.out.println("student-number="+student.getStudentnumber().getNumber());   
  StudentNumber studentnumber = (StudentNumber)session.load(StudentNumber.class, 1);        
  System.out.println("使用studentnumber对象获取学生信息");        
  System.out.println("student-name="+studentnumber.getStudent().getName());       
  System.out.println("student-number="+studentnumber.getNumber());       
  session.getTransaction().commit();          
}catch(Exception e){             
  e.printStackTrace();              
  session.getTransaction().rollback();          
}finally{             
  HibernateUnit.closeSession(session);     
 }      
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值