Hibernate中提供了两个级别的缓存:
一级缓存是session的缓存,它属于session的生命周期,session关闭后缓存也将清除.这就说明用session来提升性能的能力有限,而二级缓存是sessionFactory级别的,可以做更多的事情,但是默认是不开启的,我们想要使用,就必须先开启.在主配置文件中添加以下代码来开启二级缓存:
<property name="cache.use_second_level_cache">true</property>
光开启还不够,还要提供二级缓存的实现,需要给定缓存的提供商,有多种提供商可供选择,EhCacheProvider是一个专业的缓存提供商,在这里就使用它为hibernate的二级缓存服务.给出配置文件的相关配置:
<ehcache>
<!-- 在内存中存不下的时候,存放的临时目录 -->
<diskStore path="c:/ehcache"/>
<!--
maxElementsInMemory:可存10000个对象,超出后存入临时目录
eternal:设置对象是否为永久的,true表示永不过期,此时将忽略timeToIdleSeconds 和 timeToLiveSeconds属性; 默认值是false
timeToIdleSeconds:设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。
如果此值为0,表示对象可以无限期地处于空闲状态。
timeToLiveSeconds:设置对象生存最长时间,超过这个时间,对象过期。
如果此值为0,表示对象可以无限期地存在于缓存中. 该属性值必须大于或等于 timeToIdleSeconds 属性值
overflowToDisk:设置基于内在的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
</ehcache>
到此才算是完全开启,但是,光开启还不够!需要指定哪些类需要缓存,不需要的就不指定.如果有哪个类更新频率很快,比如新闻、首页之类的,就不需要缓存.把类缓存起来称为类缓存.
<class-cache usage="read-write" class="..senondcache.Department"/>
<class-cache usage="read-write" class="..senondcache.Employee"/>
二级缓存中的类缓存,只适用于使用id查询的方式,比如get()或load(),对于使用HQL的方式不可以缓存,比如"FROM Department d WHERE d.id=1"就不会缓存,比如以下就可以缓存:
@Test
public void testSecondCache() {
// ==========================================================
// 第一个Session
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// --------------------------------------------------------------
Department department = (Department) session.get(Department.class, 1);
System.out.println(department);
System.out.println(department.getEmployees());
// --------------------------------------------------------------
tx.commit();
session.close();
System.out.println("/n----------/n");
// ==========================================================
// 第二个Session
session = sessionFactory.openSession();
tx = session.beginTransaction();
// --------------------------------------------------------------
Department department2 = (Department) session.get(Department.class, 1);
System.out.println(department2);
System.out.println(department2.getEmployees());
// --------------------------------------------------------------
tx.commit();
session.close();
}
如果想使用查询缓存,还要在主配置文件中打开"开关":
<property name="cache.use_query_cache">true</property>
但是这样还不够,没有缓存哪条语句,在程序中指定:
@Test
public void testQueryCache() {
// ==========================================================
// 第一个Session
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// --------------------------------------------------------------
Department department = (Department) session.createQuery(//
"FROM Department d WHERE d.id=?")//
.setParameter(0, 1)//
.setCacheable(true)// 把查询语句缓存起来,以后使用就是使用缓存了
.uniqueResult();
System.out.println(department);
// --------------------------------------------------------------
tx.commit();
session.close();
System.out.println("/n----------/n");
// ==========================================================
// 第二个Session
session = sessionFactory.openSession();
tx = session.beginTransaction();
// --------------------------------------------------------------
Department department2 = (Department) session.createQuery(//
"FROM Department d WHERE d.id=?")//
.setParameter(0, 1)//
.setCacheable(true)// 使用查询缓存
.uniqueResult();
System.out.println(department2);
// --------------------------------------------------------------
tx.commit();
session.close();
}
如果类中有集合,则集合不会缓存进来,除非设置集合缓存:
<collection-cache usage="read-write" collection="..senondcache.Department.employees"/>
还有另外一种缓存,叫时间戳缓存.
时间戳缓存就是指定Hibernate的二级缓存会自动的检测,如果使用了Update或Delete语句,则把一些数据清出缓存,但是它只会清出二级缓存,如果要更新一级缓存,必须使用refresh()方法.
最后还有一个和缓存相关的,使用Query对象.
Query.list()不会使用缓存,除非调用了.setCacheable(true)才可以,但是HQL一变或参数变了,就不会再用缓存的结果了.
但是Query.iterate()会使用类缓存,原理是:
- 先执行一个查询,查询所有的符合条件的id
- 再使用每一个对象时,先根据id找缓存,如果找不着,就会生成一个select .. where id=? 的查询
- 就是说会有n+1次查询的问题(n是指定符合条件的数据量,1是指定查询id的SQL语句)
@Test
public void testQueryIterate() {
// ==========================================================
// 第一个Session
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// --------------------------------------------------------------
List list = session.createQuery("FROM Department d WHERE d.id<=2").list();
for(Object obj : list){
System.out.println(obj);
}
// --------------------------------------------------------------
tx.commit();
session.close();
System.out.println("/n----------/n");
// ==========================================================
// 第二个Session
session = sessionFactory.openSession();
tx = session.beginTransaction();
// --------------------------------------------------------------
Iterator iter = session.createQuery("FROM Department d WHERE d.id<=3").iterate();
while(iter.hasNext()){
System.out.println(iter.next());
}
// --------------------------------------------------------------
tx.commit();
session.close();
}
分享到:
相关推荐
Hibernate3.6-Final-CHM带搜索API
【hibernate3.6-jar包】是一个与Java编程相关的资源,主要涉及ORM(对象关系映射)框架Hibernate的3.6版本。Hibernate是一个开源的库,它允许开发人员在Java应用程序中使用面向对象的方式来操作数据库,从而避免了...
6. **性能优化**:3.6 版本对缓存机制进行了优化,支持更高效的二级缓存策略,同时优化了查询执行性能。 7. **支持JPA 2.0**:Hibernate 3.6 兼容了Java Persistence API 2.0 规范,使得开发者可以选择使用标准的 ...
hibernate3.6 对应的 hibernate-validator-4.1.0
在IT行业中,二级缓存是一种优化数据库访问性能的重要技术,特别是在使用ORM框架(如Hibernate)、权限管理框架(如Shiro)以及SQL映射框架(如MyBatis)时。二级缓存可以存储经常访问的数据,避免频繁地从数据库中...
本篇文章将深入探讨Hibernate的二级缓存机制,以及如何进行一级缓存与二级缓存的同步,同时还会介绍二级缓存的配置文件设置。 一级缓存是Hibernate默认提供的缓存,每个SessionFactory实例都有一个一级缓存。当对象...
本篇主要关注的是Hibernate的二级缓存,这是一个提高应用性能的关键特性。 一级缓存是Hibernate内置的Session缓存,每个Session都有自己的缓存,用于存储实体对象,它可以避免频繁地与数据库进行交互,提高性能。...
总结来说,Hibernate 的一级缓存和二级缓存都是为了提高数据访问效率,但它们在范围和并发控制方面有所不同。一级缓存是事务级别的,保证了数据的强一致性,而二级缓存提供了更多的灵活性,可以跨事务共享,但需要...
8. **缓存机制**:Hibernate提供了一级缓存(Session级别的缓存)和二级缓存(SessionFactory级别的缓存),能有效提高性能。同时,还支持第三方缓存服务如Ehcache。 9. **实体生命周期**:Hibernate管理对象的生命...
5. **第二级缓存**:为提高性能,Hibernate 3.6引入了第二级缓存机制。它允许数据在多个会话间共享,减少对数据库的访问。`@Cacheable`注解可标记为可缓存的实体,而`@Cache`注解用于配置缓存策略。 6. ** Criteria...
ehcache 二级缓存 配置使用的jar包 配置如下: <!-- 启用二级缓存 --> <property name="hibernate.cache.use_second_level_cache">true <!-- 查询的二级缓存配置 --> <property name="hibernate....
6. **二级缓存**:Hibernate 3.6提供了对二级缓存的支持,允许开发者配置缓存插件如EhCache,提高数据访问效率。二级缓存可以存储实体对象,减少对数据库的直接访问。 7. **实体生命周期管理**:Hibernate 理解对象...
**hibernate一级缓存、二级缓存和查询缓存** 在Java的持久化框架Hibernate中,缓存机制是提高应用程序性能的关键要素。缓存能够减少数据库的访问次数,提高数据读取速度,并且在一定程度上降低了系统的负载。本文将...
7. **缓存机制**: Hibernate支持一级缓存(Session级别的缓存)和二级缓存(SessionFactory级别的缓存),可以提高数据访问速度。 8. **性能优化**: 通过批处理、懒加载、预加载、缓存等技术,可以有效地提升...
Hibernate 3.6 Final所有的jar包,以及Hibernate Tools 中的hibernate-tools.jar 和 freemarker.jar 。 本jar包用于使用hibernate-tools生成POJO所需要的依赖库
本篇将深入探讨Hibernate的一级缓存和二级缓存,以及查询缓存的配置和使用。 ### 一级缓存 一级缓存是Hibernate默认提供的缓存,它是Session级别的,每个Hibernate Session都有一个私有的、本地的一级缓存。当我们...
以EhCache为例,我们需要在项目中引入ehcache-core或ehcache的依赖,并在Hibernate配置文件(hibernate.cfg.xml或persistence.xml)中启用二级缓存,添加如下配置: ```xml <property name="hibernate.cache.use_...
通常,一级缓存由Hibernate Session管理,而二级缓存则可以跨越多个Session进行共享。 在Spring Boot项目中配置Redis作为Hibernate的二级缓存,我们需要以下步骤: 1. **添加依赖**: 首先,在`pom.xml`文件中...
一级缓存是每个Session内部的缓存,而二级缓存则是SessionFactory级别的,它可以被多个Session共享。二级缓存主要由第三方缓存提供者如Ehcache、Infinispan等实现,它们将数据存储在内存或磁盘中,以便于快速访问。 ...
jar包,官方版本,自测可用