摘自圣思园 19.Hibernate的对象检索策略深度解析.avi 后半部分
一对一映射:
主键关联。
测试数据:
映射配置文件:
----测试代码:
[b][size=large]存储代码:[/size][/b]
运行结果:
[img]http://dl2.iteye.com/upload/attachment/0091/3394/0ffe7a9e-1e73-3aed-a061-46a87243cd4b.jpg[/img]
[size=large][b]查询代码:[/b][/size]
运行查询代码的时候, hibernate会自动发出[b]左外连接的SQL查询语句[/b],如下:
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对象也被赋值,如图所示:
[img]http://dl2.iteye.com/upload/attachment/0091/3439/e49e4147-5dbb-3e6b-b6a5-20cf4e37289a.jpg[/img]
====================[size=x-large][b]关于一对一的延迟加载[/b][/size]=============
在这里我们用的是get方法,Hibernate使用左外连接直接获取了Student所对应的IDCard。 但是如果我们想通过延迟加载来获取IDcard,那就必须在映射配置文件中做一些改动。
在主表Student中的<one-to-one>加入属性constrained="true",该属性默认值为false。
[i]one-to-one的单向关联中,如果constrained=false,则会在查询时就全部取出来,用left outer join的方式。如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。[/i]
此时执行代码如下:
-- 这里要注意的是IdCard映射文件应该配置延迟加载为true,当然Hibernate默认的延迟加载就是true。 所以不去配置也可以。 但是如果被配置成false,这里就不会实现延迟加载。
一对一映射:
主键关联。
测试数据:
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>
----测试代码:
[b][size=large]存储代码:[/size][/b]
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();
运行结果:
[img]http://dl2.iteye.com/upload/attachment/0091/3394/0ffe7a9e-1e73-3aed-a061-46a87243cd4b.jpg[/img]
[size=large][b]查询代码:[/b][/size]
Session session=HibernateUtil.openSession();
Student s=(Student) session.get(Student.class, "4028bd81427560bc01427560c0120000");
System.out.println(s.getName());
System.out.println(s.getIdCard().getName());
运行查询代码的时候, hibernate会自动发出[b]左外连接的SQL查询语句[/b],如下:
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对象也被赋值,如图所示:
[img]http://dl2.iteye.com/upload/attachment/0091/3439/e49e4147-5dbb-3e6b-b6a5-20cf4e37289a.jpg[/img]
====================[size=x-large][b]关于一对一的延迟加载[/b][/size]=============
在这里我们用的是get方法,Hibernate使用左外连接直接获取了Student所对应的IDCard。 但是如果我们想通过延迟加载来获取IDcard,那就必须在映射配置文件中做一些改动。
在主表Student中的<one-to-one>加入属性constrained="true",该属性默认值为false。
[i]one-to-one的单向关联中,如果constrained=false,则会在查询时就全部取出来,用left outer join的方式。如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。[/i]
此时执行代码如下:
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,这里就不会实现延迟加载。