一对一映射:
主键关联。
测试数据:
public class Student { private String id; private String name; private IdCard idCard; } public class IdCard { private String id; private int number; private Student stu; } //不管是得到IdCard还是Student,都会得到相应的一对一关联的对象。
映射配置文件:
idcard.xml <hibernate-mapping package="com.lj.zhang.Student"> <class name="IdCard" table="test_idcard"> <id name="id" column="id"> <!-- foreign这里是用外联table的已经生成的主键 --> <generator class="foreign"> <!-- name=property是固定参数,表示用外联的student的id --> <param name="property">stu</param> </generator> </id> <!-- 注意这里column不能写成number,否则oracle会报错-- ORA-00904:标示符无效 --> <property name="number" column="card_number" type="integer"/> <one-to-one name="stu" class="com.lj.zhang.Student.Student"/> </class> </hibernate-mapping> student.xml <hibernate-mapping package="com.lj.zhang.Student"> <class name="Student" table="test_student"> <id name="id" column="id" type="string"> <generator class="uuid"> </generator> </id> <property name="name" column="name" type="string" /> <one-to-one name="idCard" class="IdCard" cascade="all" /> </class> </hibernate-mapping>
----测试代码:
存储代码:
Session session=HibernateUtil.openSession(); Student s=new Student("li",null); IdCard card=new IdCard(123,s); s.setIdCard(card); Transaction tx=session.beginTransaction(); session.save(s); tx.commit();
运行结果:
查询代码:
Session session=HibernateUtil.openSession(); Student s=(Student) session.get(Student.class, "4028bd81427560bc01427560c0120000"); System.out.println(s.getName()); System.out.println(s.getIdCard().getName());
运行查询代码的时候, hibernate会自动发出 左外连接的SQL查询语句,如下:
Hibernate: select student0_.id as id1_4_1_, student0_.name as name2_4_1_, idcard1_.id as id1_1_0_, idcard1_.card_number as card2_1_0_ from test_student student0_ left outer join test_idcard idcard1_ on student0_.id=idcard1_.id where student0_.id=?
由于发出的是left outer join,此时的Student中所对应的IdCard对象也被赋值,如图所示:
==================== 关于一对一的延迟加载=============
在这里我们用的是get方法,Hibernate使用左外连接直接获取了Student所对应的IDCard。 但是如果我们想通过延迟加载来获取IDcard,那就必须在映射配置文件中做一些改动。
在主表Student中的<one-to-one>加入属性constrained="true",该属性默认值为false。
one-to-one的单向关联中,如果constrained=false,则会在查询时就全部取出来,用left outer join的方式。如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。
此时执行代码如下:
Student s=(Student) session.load(Student.class, "4028bd814275cf19014275cf1c560000"); System.out.println(s.getName());//Hibernate: select student0_.id as id1_4_0_, student0_.name as name2_4_0_ from test_student student0_ where student0_.id=? li System.out.println(s.getIdCard().getNumber());//Hibernate: select idcard0_.id as id1_1_1_, idcard0_.card_number as card2_1_1_, student1_.id as id1_4_0_, student1_.name as name2_4_0_ from test_idcard idcard0_ left outer join test_student student1_ on idcard0_.id=student1_.id where idcard0_.id=? 123
-- 这里要注意的是IdCard映射文件应该配置延迟加载为true,当然Hibernate默认的延迟加载就是true。 所以不去配置也可以。 但是如果被配置成false,这里就不会实现延迟加载。