hibernate的一级缓存(六)

来源:互联网 发布:照片白边框软件 编辑:程序博客网 时间:2024/06/05 07:33

一、 什么是缓存

* 其实就是一块内存空间,将数据源(数据库或者文件)中的数据存放到缓存中.再次获取的时候 ,直接从缓存中获取.可以提升程序的性能!

二、 Hibernate框架提供了两种缓存

* 一级缓存 -- 自带的不可卸载的.一级缓存的生命周期与session一致.一级缓存称为session级别的缓存.
* 二级缓存 -- 默认没有开启,需要手动配置才可以使用的.二级缓存可以在多个session中共享数据,二级缓存称为是sessionFactory级别的缓存.

三、 Session对象的缓存概述

* Session接口中,有一系列的java的集合,这些java集合构成了Session级别的缓存(一级缓存).将对象存入到一级缓存中,session没有结束生命周期,那么对象在session中存放着
* 内存中包含Session实例 --> Session的缓存(一些集合) --> 集合中包含的是缓存对象!

四、 证明一级缓存的存在

*先保存一个对象,然后在查询。如果,有一级缓存,就不会去数据库里面查询

@Testpublic void testSessionLevelCache() {Session session = HibernateUtils.getSession();Transaction tx = session.beginTransaction();User user = new User();user.setName("wade");user.setAge(34);// 保存用户,user存入到一级缓存Serializable id = session.save(user);// 获取对象,不会发出select的sql语句User existUser = session.get(User.class, id);System.out.println(existUser);// 提交事务之后,数据才会真正的到数据库里面去tx.commit();// 释放资源session.close();}

如上图所示,查询的时候没有发出select的sql语句。

* 在同一个Session对象中两次查询,可以证明使用了缓存


如上图所示,只发出了一条sql语句。

五、快照机制(SnapShot)

一级缓存是如何实现的呢?通过快照机制。

分析一段代码,如下:

@Testpublic void run4() {Session session = HibernateUtils.getSession();Transaction tx = session.beginTransaction();User user = session.get(User.class, 1);user.setName("隔离老王");tx.commit();session.close();}
当执行
Session session = HibernateUtils.getSession();
session就准备好了。session的存储区域分为“缓存区域”和“快照区域”。

当执行

User user = session.get(User.class, 1);
“缓存区域”和“快照区域”分别保存了一份数据库中查到的数据。

当执行

user.setName("隔离老王");
会修改“缓存区域”里面的值。

当执行

tx.commit();
提交之前:session会对比“缓存区域”和“快照区域”的数据是否一致,如果一致,什么都不做。如果不一致,修改数据库中的值,同时更新“快照区域”的数据。


六、控制Session的一级缓存

* Session.clear() -- 清空缓存。
* Session.evict(Object entity)         -- 从一级缓存中清除指定的实体对象。
* Session.flush() -- 刷出缓存

6.1 clear()演示


如上图,clear()之后,缓存被清除了,第二次获去的时候就要去查数据库

6.2 evict()演示


如上图,发出了两条sql语句,证明缓存中user对象被清空了

6.3 flush()

一般情况下,要commit的时候,才会去对比“缓存区域”和“快照区域”。而,flush()的作用便是提前对比。


如上图,还没执行commit(),就已经生成了update的sql语句。如果不提交事务的话,虽然会生成SQL语句,但数据库中的数据并不会改变。