10.延迟加载、脏检查及刷新缓冲机制

目录


1. Hibernate基本介绍及下载

2. Hibernate核心配置文件(hibernate.cfg.xml)

3. Hibernate映射文件(实体类名.hbm.xml)

4. Hibernate(Hibernate Query Language,Hibernate查询语言)

5. Hibernate基本操作具体使用

6. Hibernate关联映射(多对一、双向一对多、双向多对多)

7. Hibernate连接查询

8. Hibernate注解及其详细使用(在实体类中配置映射文件)

9. Hibernate中的Java对象的三种状态

10. 延迟加载、脏检查及刷新缓冲机制


延迟加载、脏检查及刷新缓冲机制

  • 目录
  • Hibernate延迟加载
    • 立即加载存在的不足?
    • 类级别的查询策略
    • Dept对象引用的集合代理类实例何时初始化
      • (1)会话关闭前
      • (2)会话关闭前
    • 增强延迟加载
    • 多对一关联查询策略
  • 脏检查及刷新缓冲机制
    • 脏检查
    • 刷新缓存机制
      • (1)应用程序显式调用Session的flush()方法
      • (2)应用程序调用Transaction的commit()方法


Hibernate延迟加载

立即加载存在的不足?

(1)会执行不必要的查询语句,影响查询性能
(2)可能会加载大量不需要的对象,增加系统开销,浪费内存空间

Hibernate允许在对象——关系映射文件中使用lazy属性配置加载策略,并且可以为①类级和②关联级两个级别,分别进行控制。

用于设定加载策略的lazy属性

加载策略 描述
类级别 元素中lazy属性的可选值为true(延迟加载)和false(立即加载)。默认值为true
一对一关联级别 元素中lazy属性的可选值为true(延迟加载)、extra(增强延迟加载)、false(立即加载)。默认值为true
多对一关联级别 元素中lazy属性的可选值为proxy(延迟加载)、no-proxy(无代理延迟加载)和false(立即加载)。默认值为proxy

类级别的查询策略

类级别的可选加载策略包括立即加载和延迟加载,默认为延迟加载
(1)如果元素的lazy属性为true,表示采用延迟加载;
(2)如果元素的lazy属性为false,表示采用立即加载;

立即加载使用Session的load方法时,Hibernate会立即执行SQL语句
(1)如果程序加载一个持久化对象的目的是访问它的属性,则可以采用立即加载
(2)如果程序加载一个持久化对象的目的仅仅是获得它的引用,则可以采用延迟加载


一对多和多对多关联的查询策略
在映射文件中,用元素的lazy属性来配置一对多即多对多关联关系的加载策略。

元素的lazy属性的取值决定了emps集合被初始化的时机,即到底是在加载Dept对象时就被初始化,还是在程序访问emps集合时被初始化。

执行Session的get()方法时,对于Dept对象采用类级别的立即加载策略。对于Dpet对象的emps集合(即与Dept关联的所有Emp对象),采用一对多关联级别的立即加载策略。

对于元素,应该优先考虑使用默认的延迟加载策略
Session的get()方法返回的Dept对象中,emps属性引用一个设置没有被初始化的集合代理类实例。
换句话说,此时emps集合中没有存放任何Emp对象。只有当emps集合代理类被初始化时,才能会到数据库中查询所有与Dept关联的所有Emp对象

Dept对象引用的集合代理类实例何时初始化

(1)会话关闭前

应用程序第一访问它的iterator()、size()、isEmpty()或contains()
方法:

Set emps = dept.getEmps();
// 导致emps集合代理类实例被初始化
Iterator empIterator = emps.iterator();

(2)会话关闭前

通过org.hibernate.Hibernate类的initialize()静态方法初始化

Set emps = dept.getEmps();
// 导致emps集合代理类实例被初始化
Hibernate.initialize(emps);

增强延迟加载

元素中配置lazy属性为“extra”,表明采用增强延迟加载策略

增强延迟加载策略能进一步延迟Dept对象的emps集合代理类实例的初始化时机。

当程序第一次访问emps属性的iterator()方法时,会导致emps集合代理类实例的初始化,而当程序第一次访问emps属性的size()、contains()和isEmpty()方法时,Hibernate不会初始化emps集合代理实例,仅通过特定的selete语句查询必要的信息

多对一关联查询策略

在映射文件中元素中的lazy属性


脏检查及刷新缓冲机制

Session是Hibernate向应用程序提供的持久化操纵的主要接口,它提供了基本的保存、更新、删除和加载Java对象的方法。

Session具有一个缓存,可以管理和跟踪所有持久化对象。在某个时间点,Session会根据缓存中对象的变化来执行相关的SQL语句,将对象发生的变化同步到数据库中。换句话说就是将数据库同步为与Session缓存一致这种过程称为刷新缓存

脏检查

当对象被加入Session缓存中时,Session会为对象的值类型的属性复制一份快照。操作中,属性发生改变,对象即成为脏对象。

事务提交时,Hibernate会对Session中持久状态的对象进行检测,即比较对象的当前属性与它的快,以判断对象的属性是否发生了变化,这种判断称为脏检查

如果对象发生了改变,Session会根据脏对象的最新属性值来执行相关的SQL语句,将变化更新到数据库中,以确保内存中的对象数据与数据库中的数据一致。


刷新缓存机制

当Session缓存中对象的属性发生改变时,Session并不会立即执行脏检查和执行相关的SQL语句。而是在特定的时间点,即刷新缓存时才执行。

这使得Session能够把多次变化合并为一条或者一批SQL语句,减少了访问数据库的次数,从而提高了应用程序的数据访问性能。

在默认情况下,Session会在以下时间点刷新缓存

(1)应用程序显式调用Session的flush()方法

会触发脏检查,然后向数据库提交事务

(2)应用程序调用Transaction的commit()方法

在提交事务时执行刷新缓存的动作,可以减少访问数据库的频率,尽可能缩短当前事务对数据库中相关资源的锁定时间


你可能感兴趣的:(Hibernate,hibernate,java,servlet)