从昨晚后半夜开始下午,现在外面的雪还没停,这是来北京后最大的一场雪。早上6:30起床,然后去吃早餐。今天是元旦假期的最后一天,幸好乘车的人不多,很快就坐上了车。如果是平时可能得在大雪里走几站,甚至走到学校。气温还可以,在外面等车时,雪好美!
今日继续讲解hibernate,也是hibernate课程的最后一天。Hibernate的内容非常多,如果详细着讲估计还得两天,但课程安排是三天。大部分之前的学生说外面用hibernate的很少!~~ 无奈!继续上一次课程…。
一、Hibernate的检索策略
上一次课程我们学习了类级别的检索策略和关联级别的一对多检索策略,简单复习一下:
一对多关联检索:
Fecth lazy
|
True
|
false
|
extra
|
Join
|
迫左
|
迫左
|
迫左
|
Select
|
延迟
|
立即
|
延迟(特别)
|
subselect
|
|
|
|
Fecth的优先级别高于lazy
延迟(特别):select count(id) from orders where cid=?
Subselect:使用嵌套子查询,批量查询的时候。
多对一关联检索:
Fecth lazy
|
false
|
proxy
|
No-proxy
|
Join
|
迫左
|
迫左
|
迫左
|
Select
|
立即
|
延迟:对端类级别是延迟
立即:对端类级别是立即
|
|
表单所属的客户,客户是表单的一级关联,再取出客户对应的所有表单,此时表单是前一个表单的二级关联。一级关联、二级关联,两次左外连接使用一条语句的话,会降低性能。所以使用了一条左边连接查询和一条查询语句。这就是著名的N+1查询。
hibernate3.0的所有检索策略都为延迟
接下来我们继续学习关联级别的一对一检索策略与多对多检索策略。
1.一对一检索策略
一对一关联关系是一种什么样的关系?一对一关系不可以把他们定义为一个类吗?把他们放在一个表里不可以吗?当然可以!
一对一关联两种方案:
1).外键关联,此种解决方案有两种方法:
老徐举的例子,一个用户表对应一个地址。为什么要这么做?假设地址中包含大字段,这样可以减少资源的浪费,提高访问性能。
l 方法一、就是在多对一关联的元素节点中添加一个unique=”true”属性便形成了一对一关联。
在用户类的映射文件中添加:
<!-- 影射一对一外键关联用many-to-one进行模拟,增加唯一性约束 -->
<many-to-one name="addr" column="aid" class="AddrFk" unique="true" />
|
在地址类的映射文件中添加:
<one-to-one name="user" property-ref="addr"/>
|
l 方法二、直接使用一对一关系:
在用户类的映射文件中添加:
<!-- 影射一对一主键关联 -->
<one-to-one name="addr" class="AddrPk" />
|
在地址类的映射文件中添加:
<one-to-one name="user" class="UserPk" constrained="true"/>
|
同时我们需要设置地址类映射文件的主键为:
<id name="id" column="id" type="integer">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
|
将用户表的主键设置为地址表的外键。
2).主键关联,此时子表的主键与主表的主键一一对应。有三种解决方案:
老徐举了一个例子:员工有钟点工和普通工人之分,钟点工领取的是时效工资(rate),普通工人领取的是月薪(salary)。所以我们有必要提取一个员工的超类,并分别实现钟点工和普通工人的子类。
l 方法一、我们将钟点工和普通工人的信息放到一个表里,需要在映射文件中添加:
<!-- 区分符 -->
<discriminator column="etype" type="string" length="2" />
<property name="name" column="name" type="string" length="15" />
<!-- 子类(整个继承关系树对应于一个表) -->
<subclass name="HeSingle" discriminator-value="he" lazy="false">
<property name="rate" column="rate" type="float" />
</subclass>
<subclass name="SeSingle" discriminator-value="se" lazy="false">
<property name="salary" column="salary" type="float" />
</subclass>
|
注意“discriminator”元素用于定义一个额外的列,用于区分员工的类型。
l 方法二、我们为每类员工都分别建一个表,如:
<!-- 每个子类对应一个表,从表和主表间一对一关系 -->
<joined-subclass name="HeJoined" table="hib_hejoineds" lazy="false">
<key column="eid" />
<property name="rate" column="rate" type="float" />
</joined-subclass>
<joined-subclass name="SeJoined" table="hib_sejoineds" lazy="false">
<key column="eid" />
<property name="salary" column="salary" type="float" />
</joined-subclass>
|
“column="eid"”被做为外键对应主表的员工id。
l 方法三、为每类员工建立一个表,他们与主表无关各自具有全字段。但是这三个表所使用的Id是不重复的:
<union-subclass name="HeUnion" table="hib_heunions">
<property name="rate" column="rate" type="float" />
</union-subclass>
<union-subclass name="SeUnion" table="hib_seunions">
<property name="salary" column="salary" type="float" />
</union-subclass>
|
此时,我们需要使用一个特殊的主键增值生成器:
<id name="id" column="id" type="integer">
<generator class="hilo">
<param name="table">hib_hilo</param>
<param name="column">currvalue</param>
<param name="max_lo">10</param>
</generator>
</id>
|
“"max_lo"”是id取值区间,每次插入记录时,生成器会根据此值步长增长。如果我们执行的一次插入操作,插入了10条记录。那么就需要将此设置为10,以便生成器自动为我们生成10个不同的id。
2.多对多检索策略
在以前的学习中,我们知道多对多关联关系需要一个中间表,用于记录两个多对多表的对应主键。反应到映射文件中,我们需要为两个类添加set元素。我们依然使用,老师与学生的例子,一个老师可以有多个学生,一个学生可以有多个老师,映射文件如下:
老师类映射文件中的set元素:
<set name="stus" table="hib_tea_stu_links" lazy="false">
<key column="tid" />
<many-to-many class="Stu" column="sid" />
</set>
|
“column="tid"”对应中间表“hib_tea_stu_links”的老师外键。“column="sid"”对应中间表“hib_tea_stu_links”学生的外键。
学生类映射文件中的set元素:
<set name="teas" table="hib_tea_stu_links" lazy="false" inverse="true">
<key column="sid" />
<many-to-many class="Tea" column="tid" />
</set>
|
检索策略
|
优点
|
缺点
|
优先考虑使用的场合
|
立即检索
|
对应用程序完全透明,不管对象处于持久化状态还是游离状态,应用程序都可以从一个对象导航到关联的对象
|
(1)select语句多
(2)可能会加载应用程序不需要访问的对象,浪费许多内存空间。
|
(1)类级别
(2)应用程序需要立即访问的对象
(3)使用了二级缓存
|
延迟检索
|
由应用程序决定需要加载哪些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并节省内存空间。
|
应用程序如果希望访问游离状态的代理类实例,必须保证她在持久化状态时已经被初始化。
|
(1)一对多或者多对多关联
(2)应用程序不需要立即访问或者根本不会访问的对象EN-U
分享到:
Global site tag (gtag.js) - Google Analytics
|
相关推荐
标题"传智播客hibernate源码"暗示了这是一个关于Hibernate框架的源代码学习资源,可能包含了对Hibernate框架内部机制的深入解析,以及如何在实际项目中应用Hibernate的相关示例。 描述中的内容重复,进一步确认了这...
【标题】"01_传智播客hibernate教程_hibernate介绍与动手入门体验" 涉及的是一门关于Hibernate的初学者教程,旨在帮助开发者了解并掌握这一流行的Java对象关系映射(ORM)框架。Hibernate是Java开发中的一个关键工具...
在扩展Hibernate二级缓存的过程中,有几点需要注意: 1. **配置二级缓存**:需要在Hibernate配置文件中启用二级缓存,并选择合适的缓存提供商。 2. **实体缓存配置**:为需要缓存的实体类指定缓存策略,如是否缓存...
2. **二级缓存**: 可配置的缓存,通过插件如EhCache实现,跨Session共享。 3. **查询缓存**: 缓存查询结果,避免重复执行相同的HQL或SQL。 **六、性能优化** 1. **延迟加载(Lazy Loading)**: 只在真正需要时...
【压缩包子文件的文件名称列表】"00 传智播客hibernate源码"可能包含了一系列逐步讲解的材料,如课件、笔记、代码示例等,这些内容可能按照教学顺序组织,从基础概念到高级特性的实现,引导学习者一步步理解...
10. **缓存机制**:讲解Hibernate的一级缓存和二级缓存,以及如何配置和使用第三方缓存如EhCache。 11. **性能优化**:分享一些提高Hibernate性能的策略,如合理设计实体关系、优化查询、使用批处理等。 12. **...
- 第二级缓存:可配置的缓存,提高数据读取速度。 10. **事务管理**: - Hibernate支持JTA(Java Transaction API)和JDBC事务,确保数据一致性。 11. **其他功能**: - 自动建表、更新表结构。 - 查询优化,...
本资料主要基于“传智播客hibernate源码.rar”进行深入剖析,旨在帮助你理解Hibernate的核心机制,提升你的编程能力。 一、Hibernate简介 Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常...
8. **缓存机制**:Hibernate提供了一级缓存和二级缓存,能有效减少数据库访问,提高应用性能。 9. **实体生命周期**:Hibernate定义了持久化对象的生命周期状态,包括临时态、瞬时态、持久态和脱管态,理解这些状态...
6. 查询优化:涉及查询缓存、第二级缓存的配置与使用,以及如何优化HQL和SQL,提高查询性能。 7. 高级特性:可能包括级联操作、延迟加载、动态模型、多态性、关联关系的处理等。 8. 实战案例:结合具体应用场景,...
【标题】:“01_传智播客hibernate教程_hibernate” 【描述】:“hibernate_hibernate!!”这句描述简短地强调了 Hibernate 这个关键词,暗示我们将深入探讨这个流行的Java对象关系映射(ORM)框架。 【标签】:...
- 数据缓存:了解Hibernate的二级缓存机制,提高应用程序性能。 3. **Day03:高级特性** - 关联映射:深入学习一对一、一对多、多对一、多对多的关联映射,以及懒加载和立即加载策略。 - 改动追踪与脏检查:理解...
11. **缓存机制**:理解Hibernate的第一级缓存(Session级别)和第二级缓存(SessionFactory级别),以及如何配置和使用第三方缓存。 12. **性能优化**:如批处理、延迟加载、懒加载、缓存策略等提高Hibernate应用...
"03_传智播客hibernate教程_hibernate入门案例的代码优化"主要关注如何通过优化Hibernate代码来提高应用程序的性能和效率。以下是关于Hibernate的一些关键知识点: 1. **Hibernate简介**:Hibernate是Java平台上的...
【pdf讲义】通常会以更加系统和结构化的方式呈现 Hibernate 的知识体系,包含框架的安装、配置、映射文件的细节、事务处理、缓存机制(一级缓存和二级缓存)、性能优化策略等。此外,讲义可能还会涉及如何使用 ...
【hibernate传智播客】课程主要涵盖了Hibernate框架的核心概念和使用方法,这是一款流行的Java对象关系映射(ORM)工具,它简化了数据库与Java应用之间的交互。以下是关于Hibernate的一些关键知识点: 1. **对象...
【传智播客 李勇 Hibernate 讲解】 在IT领域,ORM(Object-Relational Mapping,对象关系映射)框架是将面向对象的模型与关系数据库之间进行映射的关键技术,有效地解决了“模型不匹配”(也称为“阻抗不匹配”)的...