Hibernate的一级缓存其实就是Session内置的一个Map,用来缓存它操作过的实体对象,对象的主关键字ID是Map的key,实体对象就是对应的值。所以,一级缓存是以实体对象为单位进行存储的,访问时也是以实体为单位的(直接访问属性是不能使用缓存的),并且要求使用主关键字ID来进行访问。
一级缓存是由Session提供的,所以它只存在于Session的生命周期中,当程序调用 save(),update(),saveorupdate()等方法以及调用查询接口list,filter,iterate时,如果session缓存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中,当Session关闭的时候该Session所管理的一级缓存也会立即被清除。当程序调用get(),load(),iterate(查询实体对象才支持一级缓存,查询普通属性则不支持一级缓存)时,Hibernate会先到缓存中去拿,如果缓存中已经存在目标对象,则直接拿来而不再查询数据库,否则,必须发出查询语句到数据库中查。
对于一级缓存的使用,其实大多都是由Hibernate自动维护的,我们能做的是很少的,既不能卸载它,也不能对它进行任何的配置。但是,好在 Hibernate给我们提供了两个方法可以对它进行简单的管理:session.clear(),session.evict() 。前者是清空一级缓存中所有的对象,后者是把某一个对象从一级缓存中清除。项目中,当需要进行大批量数据一次性更新时,在不知不觉中hibernate会占用大量内存,这时就应该阶段性地调用clear()方法来清空一级缓存中的对象,控制一级缓存的大小,以避免产生内存溢出的情况。
如果数据量特别大,我们一般考虑采用jdbc实现,因为它不用把大批量的数据事先加载到内存中,然后再进行更新与修改。所以不会消耗大量内存。如果jdbc也不能满足要求可以考虑采用数据本身的特定导入工具等其它办法。
1.实体类:Student.java
public class Student { private Integer id; private String name; //一系列的setter.getter方法 } |
2.映射文件:
<class name="com.sxt.hibernate.cache.entity.Student" table="sxt_hibernate_student"> <id name="id" length="4"> <generator class="native"></generator> </id> <property name="name" length="10"></property> </class> |
3.Hibernate配置文件
省略。
4. 测试方法:
public static void main(String[] args) { Session session = null; Transaction t = null; try { session = HibernateUtils.getSession(); t = session.beginTransaction(); /** * 在同一个session中发出两次load查询 */ /* //如果前面没有用session操作过此student对象,在这里会发出sql语句. Student student = (Student)session.load(Student.class, 1); System.out.println("student.name=" + student.getName()); //不会发出sql,因为load使用一级缓存 student = (Student)session.load(Student.class, 1); System.out.println("student.name=" + student.getName());*/ /** * 在同一个session中发出两次get查询 */ /* Student student = (Student)session.get(Student.class, 1); System.out.println("student.name=" + student.getName()); //不会发出sql,因为get也使用一级缓存 student = (Student)session.get(Student.class, 1); System.out.println("student.name=" + student.getName());*/ /** * 在同一个session中发出两次iterate查询实体对象 */ /* Student student = (Student)session.createQuery("from Student s where s.id=1").iterate().next(); System.out.println("student.name=" + student.getName()); //会发出查询id的sql,不会发出查询实体对象的sql,因为iterate在查询实体对象时也使用缓存 student = (Student)session.createQuery("from Student s where s.id=1").iterate().next(); System.out.println("student.name=" + student.getName());*/ /** * 在同一个session中发出两次iterate查询实体对象 */ /* //发出sql直接插name,不再插id //select student0_.name as col_0_0_ from sxt_hibernate_student student0_ where student0_.id=1 String name = (String)session.createQuery("select s.name from Student s where s.id=1").iterate().next(); System.out.println("student.name=" + name); //iterate查询普通属性,一级缓存不会缓存,所以发出sql //由此可见,一级缓存是缓存实体对象的 name = (String)session.createQuery("select s.name from Student s where s.id=1").iterate().next(); System.out.println("student.name=" + name);*/ /** * 在同一个session中先save,在发出load查询save过的数据 */ /* Student stu = new Student(); stu.setName("吴奇隆"); Serializable id = session.save(stu);//主键生成方式采用native,是个序列化的id. //不会发出sql,因为save是使用缓存的.save之后,会把对象放到一级缓存中. //再load时,直接到一级缓存中去拿就可以了. Student student = (Student)session.load(Student.class, id); System.out.println("student.name=" + student.getName());*/ /** * 向数据库中批量加入5000条数据 */ /* for (int i=0; i<5000; i++) { Student student = new Student(); student.setName("stu_" + i); session.save(student); //每20条数据就强制session将数据持久化 //同时清除缓存,避免大量数据造成内存溢出 if ( i % 30 == 0) { session.flush(); session.clear(); } }*/ /** * 在数据库中一次性更新大批量数据 */ /* Iterator students=session.createQuery("from Student s where s.id>100").iterate(); while(students.hasNext()){ Student stu =(Student)students.next(); stu.setName("n_"+stu.getName()); //将本批插入的对象立即写入数据库并释放内存 session.flush(); session.clear(); }*/ /** * Hibernate并不适合处理大批量的数据,通常我们都跳过Hibernate API,而直接采用JDBC API来做. */ /* Connection conn =session.connection(); PreparedStatement pstmt = conn.prepareStatement("update sxt_hibernate_student set name='s'||substr(name,4,8) "+"where id >100"); pstmt.executeUpdate();*/ /** * 其实批处理大量数据更新最好的解决方法就是用创建存储过程,直接利用底层数据库.这样性能最好. */ /* *create or replace procedure StudentUpdate(s_id in number) as *begin *update sxt_hibernate_student set name='n_'||name where id>s_id; *end; */ Connection conn=session.connection(); String str="{call StudentUpdate(?)}"; CallableStatement cstmt= conn.prepareCall(str); cstmt.setInt(1,100); cstmt.executeUpdate(); t.commit(); } catch (Exception e) { e.printStackTrace(); t.rollback(); } finally { HibernateUtils.closeSession(session); } /** * 开启两个session中发出load查询 */ /* try{ session=HibernateUtils.getSession(); t=session.beginTransaction(); Student student = (Student)session.load(Student.class, 1); System.out.println("student.name=" + student.getName()); }catch(Exception e){ e.printStackTrace(); t.rollback(); }finally{ HibernateUtils.closeSession(session); } try{ session=HibernateUtils.getSession(); t=session.beginTransaction(); //会发出查询语句,因为一级缓存时和session绑定的,每个session都有自己的一级缓存,不同session间不能共享一级缓存. //上一个session已经关闭了,所以此处还要发出查询语句. Student student = (Student)session.load(Student.class, 1); System.out.println("student.name=" + student.getName()); }catch(Exception e){ e.printStackTrace(); t.rollback(); }finally{ HibernateUtils.closeSession(session); }*/ } |
分享到:
相关推荐
它是一个事务范围的缓存,也就是说,每个 Hibernate Session 对应一个一级缓存,仅在当前事务中有效。一级缓存主要存储了 Session 在当前事务中加载和修改的对象实例。当 Session 执行 CRUD 操作时,对象会自动放入...
**hibernate一级缓存、二级缓存和查询缓存** 在Java的持久化框架Hibernate中,缓存机制是提高应用程序性能的关键要素。缓存能够减少数据库的访问次数,提高数据读取速度,并且在一定程度上降低了系统的负载。本文将...
**hibernate一级缓存详解** 在Java的持久化框架Hibernate中,一级缓存是其核心特性之一,它为提高数据库操作效率、减少对数据库的访问提供了重要支持。一级缓存,也称为session缓存,是每个Hibernate Session内部...
标题“Hibernate一级缓存和二级缓存”指的是Hibernate框架中的两种缓存机制,它们是提高数据访问性能的关键要素。一级缓存是Session级别的,而二级缓存是SessionFactory级别的,两者在数据库操作中起到了重要的作用...
本文将深入探讨Hibernate的一级缓存、二级缓存以及查询缓存,通过具体的实例来阐述它们的工作原理和使用方法。 首先,我们从一级缓存开始。一级缓存是Hibernate默认提供的缓存,它是每个Session级别的,也被称为...
Hibernate 一级缓存和二级缓存的区别
一级缓存是Hibernate默认提供的缓存,每个SessionFactory实例都有一个一级缓存。当对象被加载到内存中时,它们会被存储在一级缓存中。一级缓存是事务级的,意味着它只存在于当前事务内,一旦事务提交或回滚,一级...
一级缓存是Hibernate默认提供的缓存,它是Session级别的,每个Hibernate Session都有一个私有的、本地的一级缓存。当我们在Session中对对象进行 CRUD(创建、读取、更新、删除)操作时,这些对象会被自动放入一级...
一级缓存是Session级别的,每个Session都有自己的一级缓存,用于存储当前Session操作的对象。而二级缓存则是SessionFactory级别的,它跨越了多个Session,是全局共享的,可以被多个并发的Session共同使用。 二级...
《深入理解Hibernate的一级缓存与二级缓存》 Hibernate作为一款强大的ORM框架,其缓存机制是优化数据库操作性能的关键之一。缓存主要分为一级缓存和二级缓存,它们各自承担着不同的职责,共同提升了数据访问的效率...
这与一级缓存(Session级别)不同,一级缓存仅存在于单个Session生命周期内,当Session关闭时,一级缓存中的数据会丢失。二级缓存的存在减少了对数据库的直接访问,从而提高了数据读取速度。 为了启用Hibernate的二...
Hibernate 二级缓存是针对SessionFactory级别的全局缓存,与一级缓存(Session级别)不同,一级缓存只在单个Session生命周期内有效。二级缓存则允许不同Session之间共享数据,提高了数据访问效率,减少了对数据库的...
Hibernate的一级缓存是Session级别的,它自动管理对象的状态,提供瞬时、持久化和脱管状态之间的转换。然而,一级缓存的范围有限,当Session关闭时,其中的数据会被清除。为了解决这个问题,Hibernate引入了二级缓存...
它在一级缓存(Session级别的缓存)的基础上,提供了一个全局的、跨会话的数据存储层,可以显著减少对数据库的访问,从而提高系统性能。在本压缩包“hibernate二级缓存包”中,重点包含的是 Ehcache 这个流行且广泛...
在 Hibernate 中,一级缓存是默认开启的一种缓存机制,对于提高应用程序性能有着重要作用。一级缓存位于 Session 对象中,是每个 Session 的私有缓存,它存储了从数据库中读取的对象实例。 一级缓存的工作原理: 1....
在Hibernate框架中,缓存分为一级缓存和二级缓存。 一级缓存是默认开启的,它与Session对象关联,主要负责在同一个事务内部管理对象的状态。一级缓存会跟踪所有在事务中被修改的对象,确保在事务提交时仅生成必要的...
- 一级缓存:每个 Hibernate Session 对象都有一个一级缓存,它是默认开启的。当对象被加载到 Session 中,它们会被存储在一级缓存中,直到 Session 被关闭。一级缓存是事务范围的,只对当前 Session 可见。 - 二...
当我们在Session中对实体进行CRUD操作时,数据会首先被缓存到一级缓存中,同一Session内的后续查询会优先从一级缓存中获取数据,避免了频繁访问数据库。 2. **二级缓存(Second-Level Cache)**:一级缓存的局限...
用以介绍hibernate 框架的缓存机制
Hibernate的一级缓存是指Session级别的缓存,每个Session内部都有一个一级缓存,用于存储实体对象,当Session关闭时,一级缓存中的数据也会被清除。而二级缓存则是一个SessionFactory级别的缓存,它跨越多个Session...