缓存相当于Map结构,讲的是命中率,就像Entryset中的key和Value。
Hibernate中的缓存:
- 一级缓存,也叫session级别的缓存,缓存的是实体
- 二级缓存,是SessionFactory级别的缓存,缓存的也是实体
- 查询缓存,也是SessionFactory级别的缓存,它缓存的是普通结果集,但如果缓存的是实体则缓存实体的Id列表
session级别的缓存即一级缓存,不能被取消,它一直存在,随着session的关闭,缓存也会随之失效!sessionFactory级别的缓存是可以取消的,甚至不用
。
现在让我们先来看看session级别的缓存,也就是一级缓存:
- 可以通过session的load/get操作加载实体对象,通过session的list/iterate查询实体对象,这四种操作都能把实体对象放入一级缓存
如:
//将发出SQL查询语句查询实体对象的数据
Person p1 = (Person)session.load(Person.class, 1);
System.out.println(p1.getName());
//实体对象已经被缓存,所以下列操作不再发出SQL语句
Person p2 = (Person)session.load(Person.class, 1);
System.out.println(p2.getName());
因此可以这样理解,持久化对象都在一级缓存里边,如果session关闭之后,那么当前session对象中的一级缓存已经被清空
,这时候你再启动一个session的话,他还是会发送sql语句到内存中查找那个实体,因为当前的session对象已被一级缓存给清空了。
接着看看list和iterate操作:他们都能够缓存实体到一级缓存中
//下面这个操作,会导致hibernate发出SQL语句查询两个实体对象到一级缓存中
List persons = session.createQuery(
"select p from Person p where p.id in (1,2)") .list();
for (Iterator iterator = persons.iterator(); iterator.hasNext();) {
Person p = (Person ) iterator.next();
System.out.println(p.getName());
}
//不会再发出查询语句
Person cp = (Person )session.load(Person .class, 1);
System.out.println(cp.getName());
//实体对象已经被缓存,所以下列操作不再发出SQL语句
Person cp1 = (Person )session.get(Person .class, 1);
System.out.println(cp1.getName());
//实体对象已经被缓存,所以下列操作不再发出SQL语句
Person cp2 = (Person )session.get(Person .class, 2);
System.out.println(cp2.getName());
//因为本实体对象不在一级缓存中,所以下面将发出SQL语句查询实体对象
Person cp3 = (Person )session.get(Person .class, 3);
System.out.println(cp3.getName());
具体的list和iterate区别见1+N文章!
清空一级缓存,表示这个对象不再是持久化对象了,他应该是个离线的对象。
session.clear()清空所有的一级缓存,session.evict()清楚一级缓存中某个实体缓存。
Person p = (Person)session.get(Person.class, 4);
p.setName("士兵乙");
//清空一级缓存里面的所有的持久化对象!
//session.clear();
//清楚一级缓存里面的某个持久化对象!
session.evict(p);
session.getTransaction().commit();
- 再看看下面更新关联丢失的解决之道:
//这是一个离线对象,假设这个对象从呈现层中传过来的!
Person p = new Person();
p.setId(1);
p.setQq("1234567");
p.setAddress("上海!");
p.setName("xxxxx");
//假设为了不丢失Person与Group对象之间的关联,我们先加载原来的Person
Person oldp = (Person)session.get(Person.class, p.getId());
//把原来的关联关系,设置到新的对象中
p.setGroup(oldp.getGroup());
//更新新的对象!
//update方法会把p对象放入一级缓存
//上面的get操作,把oldp对象也放入了一级缓存
//p对象和oldp对象,不是同一个对象
//但p对象和oldp对象具有相同的数据库标识!
//所以下面的update操作,将抛出异常:org.hibernate.NonUniqueObjectException
: a different object
//with the same identifier value was already associated with the session翻译过来如下:
//因为在Hibernate中,同一个session中,不允许存在两个具有相同数据库标识的同一种类型的实体对象
//session.update(p);
session.getTransaction().commit();
那应该怎么解决呢?方法一:
//解决上述问题的方法之一:就是
//利用session一级缓存的管理机制,先把oldp对象从一级缓存中清除
session.evict(oldp);
session.update(p);
解决它的第二个办法:
//解决上述问题的方法之二:
//利用session中的merge方法来更新p对象!
//merge方法,相当于把某个离线状态的对象拷贝到某个对应的持久化对象中
//相当于把p拷贝到oldP中,从而更新oldP中所有的属性
session.merge(p);
-
在批量插入数据时如有100万条数据时,这时不可能一次性把这么多数据全部持久化到数据库中,我们应当批量地插入,如100条的插入,当插入了100条后,即全部写进去后,也就是flush干净 了,这时候把一级缓存清空一下以便下一批数据的批量插入,从而保证缓存的可用,而不会导致一次性插入大量数据致使内存溢出的情况
for(int i=0; i<1000000000; i++){
Person p = new Person();
p.setAddress("xxx");
//...p.setXXX
session.save(p);
if(i % 100 == 0){
session.flush();
session.clear();
}
}
分享到:
相关推荐
本文将详细介绍Hibernate的一级缓存和二级缓存。 一级缓存,也称为Session缓存,是Hibernate内置的默认缓存。它是一个事务级别的缓存,每个持久化类的实例都有唯一的OID(Object Identifier)。当我们在同一个...
它是一个事务范围的缓存,也就是说,每个 Hibernate Session 对应一个一级缓存,仅在当前事务中有效。一级缓存主要存储了 Session 在当前事务中加载和修改的对象实例。当 Session 执行 CRUD 操作时,对象会自动放入...
一级缓存是Hibernate默认提供的缓存,它是Session级别的,每个Hibernate Session都有一个私有的、本地的一级缓存。当我们在Session中对对象进行 CRUD(创建、读取、更新、删除)操作时,这些对象会被自动放入一级...
**hibernate一级缓存、二级缓存和查询缓存** 在Java的持久化框架Hibernate中,缓存机制是提高应用程序性能的关键要素。缓存能够减少数据库的访问次数,提高数据读取速度,并且在一定程度上降低了系统的负载。本文将...
在Hibernate框架中,一级缓存和二级缓存各自承担着不同的角色,通过合理的设计和配置,可以充分发挥缓存的优势,显著提升系统的性能和用户体验。在实际项目中,开发者应根据具体需求灵活运用这两种缓存机制,以达到...
**hibernate缓存策略详解** Hibernate作为Java领域中广泛使用的ORM框架,其在处理大量数据时,为了提高性能和减少数据库的访问压力,引入了缓存机制。本文将深入探讨Hibernate的缓存策略,包括一级缓存、二级缓存...
标题“Hibernate一级缓存和二级缓存”指的是Hibernate框架中的两种缓存机制,它们是提高数据访问性能的关键要素。一级缓存是Session级别的,而二级缓存是SessionFactory级别的,两者在数据库操作中起到了重要的作用...
除了了解一级缓存和二级缓存的基本概念外,还需要掌握它们的工作原理以及如何配置不同的缓存策略来满足具体的应用需求。 ##### 3.1 缓存策略 Hibernate支持多种缓存策略,每种策略都有其特定的应用场景: - **...
一级缓存是Hibernate默认提供的缓存,每个SessionFactory实例都有一个一级缓存。当对象被加载到内存中时,它们会被存储在一级缓存中。一级缓存是事务级的,意味着它只存在于当前事务内,一旦事务提交或回滚,一级...
《深入理解Hibernate的一级缓存与二级缓存》 Hibernate作为一款强大的ORM框架,其缓存机制是优化数据库操作性能的关键之一。缓存主要分为一级缓存和二级缓存,它们各自承担着不同的职责,共同提升了数据访问的效率...
本文将深入探讨Hibernate的一级缓存、二级缓存以及查询缓存,通过具体的实例来阐述它们的工作原理和使用方法。 首先,我们从一级缓存开始。一级缓存是Hibernate默认提供的缓存,它是每个Session级别的,也被称为...
在Java的持久化框架Hibernate中,一级缓存是其核心特性之一,它为提高数据库操作效率、减少对数据库的访问提供了重要支持。一级缓存,也称为session缓存,是每个Hibernate Session内部管理的一个内存结构。在本篇...
### Hibernate缓存策略详解 #### 一、理解Hibernate缓存 ##### 1.1 缓存概念 在软件开发领域,缓存技术是一项重要的优化手段,它可以显著提高应用程序的性能和响应速度。Hibernate作为一种持久层框架,其核心功能...
- **定义**:第一级缓存是在`Session`范围内维护的一个缓存区域,它是事务级别的缓存,用于存储当前`Session`中加载或保存的对象状态。 - **特点**:第一级缓存是必须存在的,无法被禁用。对于同一个OID(对象标识符...
在 Hibernate 中,一级缓存是默认开启的一种缓存机制,对于提高应用程序性能有着重要作用。一级缓存位于 Session 对象中,是每个 Session 的私有缓存,它存储了从数据库中读取的对象实例。 一级缓存的工作原理: 1....
当实体被持久化时,会自动放入一级缓存,读取数据时也会优先从一级缓存中查找。一级缓存默认开启且无法关闭,具有事务隔离性,即在同一个事务中修改的数据,只有在事务提交后才会对其他事务可见。 **三、二级缓存**...
一级缓存是Hibernate的默认行为,每个`Session`对象都有一个内部的一级缓存。当我们在`Session`内执行CRUD操作时,实体会被放入这个缓存中。一级缓存的作用是在当前事务范围内提供对象状态的持久化。这意味着,对同...
本文将深入探讨Hibernate性能优化中的一个重要概念——一级缓存,并结合给出的压缩包文件“hibernate_cache_level1”,来详细解析一级缓存的工作原理及其优化策略。 一级缓存是Hibernate内置的一种缓存机制,它存在...
这与一级缓存(Session级别)不同,一级缓存仅存在于单个Session生命周期内,当Session关闭时,一级缓存中的数据会丢失。二级缓存的存在减少了对数据库的直接访问,从而提高了数据读取速度。 为了启用Hibernate的二...