Hibernate的时间戳缓存区域

时间戳:一个详细到秒的时间点,就是一个时分秒的字符串

时间戳缓存区域存放了对于查询结果相关的表进行插入, 更新或删除操作的时间戳.
Hibernate 通过时间戳缓存区域来判断被缓存的查询结果是否过期,
其运行过程如下: (T1和T2没有规定谁先谁后的,是程序需要操作的)
T1 时刻执行查询操作(就例如一个客户1在客户端进行一次查询), 把查询结果存放在 QueryCache 区域, 记录该区域的时间戳为 T1
T2 时刻对查询结果相关的表进行更新操作(管理员在某个时间对客户查询的表进行了更新操作), Hibernate 把 T2 时刻存放在 UpdateTimestampCache 区域.
T3 时刻执行查询结果前(又有另外一个客户执行了客户1同样的查询语句), 先比较 QueryCache 区域的时间戳(T1)和 UpdateTimestampCache 区域的时间戳(T2),
   若 T2 >T1, 那么就丢弃原先存放在 QueryCache 区域的查询结果, 重新到数据库中查询数据, 再把结果存放到 QueryCache 区域;
   若 T2 < T1, 直接从 QueryCache 中获得查询结果
这就是时间戳的缓存原理:

所有的二级缓存的查询缓存遵循时间戳缓存策略,对象二级缓存和集合二级缓存不支持此策略,

例如咋们对某个对象进行了二级缓存,但同时又做了对象对应表的更新操作
测试代码如下

@Test
    public void testHibernateSecondLevelCache(){
        Employee employee = (Employee) session.get(Employee.class, 15);
        System.out.println(employee.getName()); 

        transaction.commit();
        session.close();
        System.out.println("--------------------------------------");
        session = sessionFactory.openSession();
        transaction = session.beginTransaction();
        Employee employee2=new Employee();

        employee2.setEmail("[email protected]");
        employee2.setName("jeremy");
        employee2.setSalary(8000F);
        session.save(employee2);

        Employee employee3 = (Employee) session.get(Employee.class, 15);
        System.out.println(employee3.getName());
    }

我已经设置了二级缓存了,如果二级缓存没有失效我这里应该是发送了一条select语句和一条insert语句,运行结果也是那样

Hibernate:
    select
        employee0_.ID as ID1_1_0_,
        employee0_.NAME as NAME2_1_0_,
        employee0_.SALARY as SALARY3_1_0_,
        employee0_.EMAIL as EMAIL4_1_0_,
        employee0_.DEPT_ID as DEPT_ID5_1_0_
    from
        GG_EMPLOYEE employee0_
    where
        employee0_.ID=?
AA
--------------------------------------
Hibernate:
    insert
    into
        GG_EMPLOYEE
        (NAME, SALARY, EMAIL, DEPT_ID)
    values
        (?, ?, ?, ?)
AA

也就证明了对象二级缓存不支持时间戳缓存策略。collection也是这样,

而查询缓存就支持这个策略:

代码如下:

例如运行下面测试代码:

@Test
    public void testQueryCache(){
        Query query = session.createQuery("FROM Employee e where e.id=1");
        query.setCacheable(true);

        List<Employee> emps = query.list();
        System.out.println(emps.size());
        System.out.println(emps.iterator().next().getClass());

        Employee employee=new Employee();

        employee.setEmail("[email protected]");
        employee.setName("jeremy");
        employee.setSalary(8000F);
        session.save(employee);

        emps = query.list();
        System.out.println(emps.size());

        //Criteria criteria = session.createCriteria(Employee.class);
        //criteria.setCacheable(true);
    }

运行结果:

Hibernate:
    select
        employee0_.ID as ID1_1_,
        employee0_.NAME as NAME2_1_,
        employee0_.SALARY as SALARY3_1_,
        employee0_.EMAIL as EMAIL4_1_,
        employee0_.DEPT_ID as DEPT_ID5_1_
    from
        GG_EMPLOYEE employee0_
    where
        employee0_.ID=10
1
class com.atguigu.hibernate.entities.Employee
Hibernate:
    insert
    into
        GG_EMPLOYEE
        (NAME, SALARY, EMAIL, DEPT_ID)
    values
        (?, ?, ?, ?)
Hibernate:
    select
        employee0_.ID as ID1_1_,
        employee0_.NAME as NAME2_1_,
        employee0_.SALARY as SALARY3_1_,
        employee0_.EMAIL as EMAIL4_1_,
        employee0_.DEPT_ID as DEPT_ID5_1_
    from
        GG_EMPLOYEE employee0_
    where
        employee0_.ID=10
1

我在进行了第一次HQL查询后又对了数据表进行了增加操作了,此时的数据表已经发生了改变了,此时查询缓存被关闭了(就算更新操作对我HQL语句查询的结果没影响,但是查询缓存还是被关闭了)


如果查询缓存没有被关闭,那已是发送一条select语句和一条insert语句,但是现在是发送了两条select语句,一条insert语句 ,所以证明了,当查询缓存相关的表更新后,

查询缓存会自动关闭,这一点需要记住

时间: 2024-08-02 05:01:11

Hibernate的时间戳缓存区域的相关文章

[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Hibernate之二级缓存

Hibernate缓存 缓存(Cache):计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如硬盘上的文件或数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能.缓存中的数据时数据存储源中数据的拷贝.缓存的物理介质通常是内存 Hibernate中提供了两个级别的缓存 第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存.这一级别的缓存有Hibernate管理的 第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围的缓

hibernate(九) 二级缓存和事务级别详讲

序言 这算是hibernate的最后一篇文章了,下一系列会讲解Struts2的东西,然后说完Struts2,在到Spring,然后在写一个SSH如何整合的案例.之后就会在去讲SSM,在之后我自己的个人博客应该也差不多可以做出来了.基本上先这样定下来,开始完成hibernate的东西把.这章结束后,我会将我一些hibernate的资料奉上,供大家一起学习. ---WH 一.概述 这章总的分两大块来讲解, 第一大块,hibernate的事务管理.,对于hibernate的事务管理来说,如果之前学过数

hiernate二级缓存区域

区域即是一个具有名称的高速缓存块,你可以给每一个高速缓存块设置不同的缓存策略.如果没有设置任何的缓存区域, 则所有被缓存的对象,都将使用默认的缓存策略.即:<defaultCache.../> 对于类而言,区域的名称是类名.如:cn.itcast.domain.Person(一般情况后面会跟一个.data) 对于集合而言,区域的名称是类名加属性名.如cn.itcast.domain.Person.cars(一般情况,后面会跟一个.data) hibernate的配置属性:hibernate.c

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

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

Hibernate之一级缓存

时间:2017-1-20 14:48 --一级缓存 1.什么是缓存    缓存是将数据库.硬盘上的文件中的数据,放入到缓存中.    缓存就是内存中的一块空间,当再次使用数据时,可以直接从内存中获得. 2.缓存的优点    提高程序运行的效率,缓存技术是Hibernate的一个优化手段. 3.Hibernate分为两个级别的缓存:    1)一级缓存:        Session级别的缓存,一级缓存与Session生命周期一致,是自带的,不可卸载.        一级缓存缓存的是对象的引用. 

管理 Hibernate 的二级缓存

<ehcache> <!-- 指定一个目录:当 EHCache 把数据写到硬盘上时, 将把数据写到这个目录下. --> <diskStore path="d:\\tempDirectory"/> <!-- 设置缓存的默认数据过期策略 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds=&

Hibernate的一级缓存

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

Hibernate中一级缓存和二级缓存

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