Hibernate之一级缓存

时间:2017-1-20 14:48

——一级缓存

1、什么是缓存
    缓存是将数据库、硬盘上的文件中的数据,放入到缓存中。
    缓存就是内存中的一块空间,当再次使用数据时,可以直接从内存中获得。

2、缓存的优点
    提高程序运行的效率,缓存技术是Hibernate的一个优化手段。

3、Hibernate分为两个级别的缓存:
    1)一级缓存:
        Session级别的缓存,一级缓存与Session生命周期一致,是自带的,不可卸载。
        一级缓存缓存的是对象的引用。
 
    2)二级缓存:
        SessionFactory级别的缓存,不是自带的,如果想要使用,则必须配置。

4、理解Session缓存(一级缓存)
    1)在Session接口的实现中包含了一系列的Java集合,这些Java集合构成了Session缓存,只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。
    2)当Session的save()方法持久化一个对象时,该对象被载入一级缓存,以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中,当视图get()、load()获取对象时,会判断缓存中是否存在该对象,有则返回,此时不再查询数据库,没有再查询数据库。
    3)Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被成为刷出缓存(flush)
    4)默认情况下,Session在以下时间点刷出缓存:
        *   当应用程序调用Transaction的commit()方法时,该方法先刷出缓存(session.flush()),然后再向数据库提交事务。
        *   当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会先刷出缓存,以保证查询结果能够反应持久化对象的最新状态。
        *   调用session的flush()方法。

——证明Hibernate一级缓存的存在

示例代码:

public void fun3(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

// save()方法可以向一级缓存中存放数据

Book book = new Book();

book.setName("Hibernate");

book.setAuthor("张三");

book.setPrice(50D);

Integer id = (Integer)session.save(book);

// 第一次查询会发送SQL语句

Book book1 = (Book)session.get(Book.class, 1);

System.out.println(book1);

// 第二次查询不会发送SQL语句,并且获取到的对象地址也是相同的,因为第一次查询已经将对象放入缓存了

Book book2 = (Book)session.get(Book.class, 1);

System.out.println(book2);

tx.commit();

session.close();

}

——Hibernate快照区

当session加载了customer对象后,会为customer对象的值类型的属性复制一份快照。
当刷出缓存时,通过比较对象的当前属性和快照,来判断对象的哪些属性发生了变化,如果对象的属性和快照区一致,则不执行update操作。
自动更新数据库是依赖了快照区。

快照的存才提高了Hibernate的执行效率。

可以通过断点进行查看。

示例代码:
    public void fun4(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

// 获得一个持久态对象

Book book = (Book)session.load(Book.class, 2);

book.setName("Hibernate");

/*

* 当修改对象和数据库中数据一致时,不会提交更新语句

* 通过快照区来判断数据是否一致

*/

tx.commit();

session.close();

}

——一级缓存的管理

一级缓存与Session的生命周期相关,Session的生命周期结束,一级缓存也就销毁了。

Session中的方法:
    *   flush()
        将缓存中的数据刷出到数据库。
    *   clear()
        清空缓存中所有数据。
    *   evict()
        清空指定对象一级缓存数据,使对象变为离线态。
    *   refresh()
        使用快照区将一级缓存中的数据覆盖,使一级缓存中的数据变为从数据库查询时的初始状态。

示例代码:

// 一级缓存的管理:clear() / evict()

public void fun5(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Book book1 = (Book) session.get(Book.class, 1);

Book book2 = (Book) session.get(Book.class, 2);

System.out.println(book1);

System.out.println(book2);

// session.clear(); // 清空一级缓存区域

session.evict(book1); // 清空一级缓存中的指定对象

Book book3 = (Book) session.get(Book.class, 1);

Book book4 = (Book) session.get(Book.class, 2);

System.out.println(book3);

System.out.println(book4);

tx.commit();

session.close();

}

——一级缓存的刷出时机

FlushMode类:
    常量:
        *   ALWAYS
            普通查询、手动flush()、事务提交都会刷新。
        *   AUTO(默认值)
            有些查询会刷出缓存,手动调用flush()、事务提交会刷出。
        *   COMMIT
            只有在事务提交时、手动调用flush()会刷出。
        *   MANUAL
            只有在flush()时刷出。
        *   NEVER
            已过时,用MANUAL替代。

严格程度:MANUAL > COMMIT > AUTO > ALWAYS

通过session.setFlushMode(FlushMode.AUTO)进行设置,一般不会修改其值。

——操作持久化对象的方法

1、save()
    1)session的save()方法使一个瞬时对象转变为持久态对象
    2)session的save()方法完成以下操作:
        *   把瞬时对象加入到Session缓存中,使它进入持久化状态。
        *   选用映射文件指定的标识符生成器,为持久化对象分配唯一的OID,在使用代理主键的情况下,setId()方法为瞬时对象设置OID是无效的。
        *   计划执行一条insert语句,把Customer对象当前的属性值组装到insert语句中。
    3)Hibernate通过持久化对象的OID来维持它和数据库相关记录的对应关系,当Customer对象处于持久化状态时,不允许程序随意修改它的ID。

2、update()
    1)session的update()方法使一个脱管对象转变为持久化对象,并且计划执行一条update语句。
    2)在<class>标签上设置select-brefore-update="true",会在更新之前先查询,如果数据存在并且与待更新数据一致,则不执行更新。

3、saveOrUpdate()
    1)根据对象的不同状态执行save()或update()方法。
        *   如果一个对象是瞬时态对象:执行save()方法
        *   如果对象是一个脱管态对象:执行update()方法
    如果在执行update()时设置的id不存在,会报错,可以在<id>标签上设置一个unsaved-value="-1",这样如果设置的id是-1,则会继续自动生成主键并save()

4、delete()
    将持久态对象转换为瞬时态对象。

5、get() / load()
    获得一个持久态对象。

——总结

1、Hibernate中两个基本缓存
    *   一级缓存:与Session生命周期一致
    *   二级缓存:与SessionFactory生命周期一致
2、证明一级缓存的存在
3、一级缓存的结构 - 快照区
    *   用来自动完成数据库更新操作
4、Hibernate一级缓存的管理
    *   clear()
    *   evict()
    *   flush()
    *   refresh()
5、一级缓存刷出时机
    *   ALWAYS
    *   AUTO:默认值
    *   COMMIT:事务提交/flush()时刷出
    *   MANUAL:手动flush()时刷出
6、操作持久化对象常用方法
    *   save()
    *   update()
    *   saveOrUpdate()
    *   delete()
    *   get() / load()

时间: 2024-10-10 14:32:32

Hibernate之一级缓存的相关文章

Hibernate的一级缓存

Hibernate的一级缓存其实就是Session内置的一个Map,用来缓存它操作过的实体对象,对象的主关键字ID是Map的key,实体对 象就是对应的值.所以,一级缓存是以实体对象为单位进行存储的,访问时也是以实体为单位的(直接访问属性是不能使用缓存的),并且要求使用主关键字ID来 进行访问. 一级缓存是由Session提供的,所以它只存在于Session的生命周期中,当程序调用 save(),update(),saveorupdate()等方法以及调用查询接口list,filter,iter

Hibernate学习笔记(三) — Hibernate 的一级缓存意义

什么是缓存? 缓存说白了,就是应用程序向数据库要数据,然后把一些数据,临时的放在了内存的区域中,第二次再要数据的时候,直接从内存中拿即可. 缓存需要解决的事情: 1.能把数据放入缓存 2.能把数据从缓存中取出来 3.如果缓存中的数据发生变化,需要把数据同步到数据库中 4.把数据库中的数据同步到缓存中 5.hits命中率低的对象应该及时从缓存中移走 分布式缓存: 为什么会有分布式缓存? 应用程序运行在服务器上,并发访问时,服务器压力过大,分布式缓存就是来分担服务器压力的. 分布式缓存之间的数据是同

hibernate(二)一级缓存和三种状态解析

序言 前一篇文章知道了什么是hibernate,并且创建了第一个hibernate工程,今天就来先谈谈hibernate的一级缓存和它的三种状态,先要对着两个有一个深刻的了解,才能对后面我要讲解的一对多,一对一.多对多这种映射关系更好的理 --WH 一.一级缓存和快照 什么是一级缓存呢? 很简单,每次hibernate跟数据库打交道时,都是通过session来对要操作的对象取得关联,然后在进行操作,那么具体的过程是什么样的呢? 1.首先session将一个对象加入自己的管理范围内,其实也就是把该

(转)Hibernate的一级缓存

http://blog.csdn.net/yerenyuan_pku/article/details/70148567 Hibernate的一级缓存 Hibernate的一级缓存就是指Session缓存.通过查看Session接口的实现类——SessionImpl.java的源码可发现有如下两个类:  actionQueue它是一个行动队列,它主要记录crud操作的相关信息. persistenceContext它是持久化上下文,它其实才是真正的缓存. 在Session中定义了一系列的集合来存储

hibernate学习(四)hibernate的一级缓存&amp;快照

缓存:提高效率 硬件的 CPU缓存   硬盘缓存   内存 软件的  io流缓存 hibernate  的一级缓存   也是为了操作数据库的效率. 证明一级缓存在  : Person p=session .get(Person.class, 1); Person p1=session.get(Person.class,2); Person  p2=session.get(Person.class,3); System.out.println(p=p1); 控制台输出为: select   * 

Hibernate中一级缓存和二级缓存

缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 缓存的介质一般是内存,所以读写速度很快.但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质.缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期. Hibernate的缓存包括Session的缓存和SessionFactory的缓

Hibernate中一级缓存概念以及flush与clear的区别

Hibernate采用缓存机制提高数据查询效率.缓存分为一级缓存和二级缓存,一级缓存在Session中存在,二级缓存需要手动配置. 在一级缓存中,如果数据保存到数据库中后,而session又没有关闭的话,那么这些数据会放到缓存中,再次发出查询请求,Hibernate首先检查缓存中是否有该数据,如果找到该数据,那么就不会向数据库发起查询请求而是直接将缓存中的数据取出.请看下面的例子: public class Main { public static void main(String[] args

Hibernate中一级缓存和二级缓存使用详解

一.一级缓存二级缓存的概念解释 (1)一级缓存就是Session级别的缓存,一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中,如果短时间内这个 session(一定要同一个session)又做了同一个操作,那么hibernate直接从一级缓存中拿,而不会再去连数据库,取数据: (2)二级缓存就是SessionFactory级别的缓存,顾名思义,就是查询的时候会把查询结果缓存到二级缓存中,如果同一个sessionFactory 创建的某个session执行了相同的操作,hib

Hibernate一级缓存和二级缓存深度比较

1.什么是缓存 缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 缓存的介质一般是内存,所以读写速度很快.但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质.缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期. Hibernate的一级缓存是内置的,不能被卸载. Hiberna