缓存是计算机领域的概念,它介于应用程序和永久性数据存储源(如硬盘上的文件或者
数据库)之间,其作用是降低应用程序直接写永久性数据存储源的频率,从而提高应用
的运行性能。缓存中的数据是数据存储源中数据的复制,应用程序在运行时直接读写缓
存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源。
缓存的物理解释通常是内存,而永久性数据存储源的物理介质通常是硬盘或磁盘,应用
程序读写内存的数据显然比读写硬盘的速度快。如果缓存中存放的数据量非常大,也会
用硬盘作为缓存的物理介质。
Hibernate的缓存一般分为3类
1.一级缓存:Session缓存称为一级缓存,由于Session对象的声明周期通常对应一
个数据库事务,因此它的缓存是事务范围的缓存,
2.二级缓存:SessionFactory缓存分为内存缓存和外置缓存,内置缓存是Hibernate
自带的,不可拆卸,是只读取缓存,用来存放映射元数据和预定义SQL语句。
外置缓存是一个可配置的缓存插件,默认SessionFactory不会启用这个缓存插
件。
3.查询缓存:
它是Hibernate为查询结果提供的,依赖于二级缓存。
缓存的作用范围分为3类
1.事务范围:每个事务都有自己的缓存,缓存内数据不会被多个事务并发访问。
2.进程范围:进程内的所有事务共享缓存,进程结束,缓存结束生命周期。
3.集群范围:缓存被一个或多个机器上的多个进程共享,Hibernate的二级缓存也可
以作为集群范围的缓存
hibernate的一级缓存 (一级缓存区域和快照区域)
当瞬时态对象转换为持久态对象时存入一级缓存及快照区
当持久化对象数据更新时,一级缓存区和快照区进行内容 对比 ,如果一致不
更新,如果不一致更新 数据库内容
缓存的本质是一个MAP集合, 缓存的管理 clear()/evict(customer)/flush()/
refresh()
eg:
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer liudehua = (Customer)session.get(Customer.class, 1);
liudehua.setCname("刘德华");
//session.refresh(liudehua);
session.flush();//执行该方法执行update语句
tx.commit();
hibernate的 二级 缓存
SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不
会启用这个插件。
外置缓存的数据是数据库数据 的副本,外置缓存的介质可以是内存或者硬盘。
SessionFactory的外置缓存也被称为Hibernate的二级缓存。
二级缓存是进程或集群范围内的缓存,可以被所有Session共享,其生命周期和
SessionFactory一样
二级缓存相当于一个交互地带
二级缓存的适用范围
● 很少被修改的数据。
● 不是很重要的数据,允许出现偶尔并发的数据。
● 不会被并发访问的数据。
● 参考数据。
hibernate使用二级缓存(EHCache)
3.1 在工程 中 添加 二级缓存的jar包
拷贝ehcache-1.5.0.jar到当前工程的lib目录下
依赖 backport-util-concurrent 和 commons-logging
3.2 在src下添加配置文件 ehcache.xml
3.3 zai核心配置文件 hibernate.cfg.xml 中开启二级缓存,并指定缓存的供
应商
true
org.hibernate.cache.EhCacheProvider
3.4 配置使用缓存的实体类
3.4.1 方法一:在实体类.hbm.xml中的
策略
如果要缓存集合属性,则在
3.4.2 方法二:直接在hibernate.cfg.xml的
3.5 证明二级 缓存的存在
//二级缓存是sessionFactory级别的缓存
SessionFactory sf = new
Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
User u = (User) session.get(User.class, 7);
System.out.println(u.getUname());
tx.commit();
session.close();
session = sf.openSession();
tx = session.beginTransaction();
User u2 = (User) session.get(User.class, 7);
System.out.println(u2.getUname());
tx.commit();
session.close();
sf.close();
两个查询最终只发送一条sql语句,说明第二个查询操作没有向数据库发 送请求,而是直接在二级缓存中查询
***
测试类级别的二级缓存只适用于get和load获取数据,对query接口可以
将数据放置到类级别的二级缓存中,
但是不能使用query接口的 list方法从缓存中获取数据;query接口将查
询的对象放置到二级缓存的查询缓存
使用查询缓存的步骤:
在前面Hibernate的二级缓存,只有基于ID查找对象时才会用到,对于查询则毫无
作用。为此Hibernate提供了针对查询的查询缓存。查询缓存依赖于二级缓存,
1、在 hibernate.cfg.xml中启用查询缓存
2、调用 Query 的 setCacheable(true) 方法
然后就可以使用Query.list()方法获取二级缓存中的数据