一对一外键关联单向映射
一对一的关联依然可以使用学生-学号的关系来描述。而所谓的外键关联,就是没张表都有自己独立的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);
}
}