用例子理解hibernate的一级缓存

翻译 2015年11月20日 23:44:58

缓存由ORM框架提供以便用户可以获得更快速的访问速度,同时框架本身也减少了数据库查询操作。

hibernate中的一级缓存是默认使用的,使用它你不需要操作任何事情。实际上,你不能强制关闭它。

如果我们我们知道一级缓存是和Session对象相关连的,那么理解一级缓存就会变得容易多了。我们知道Session对象由Session工厂创建,Session关闭的时候,对象丢失。同样的一级缓存只有在Session存活的时候才会有效,并且只在本Session中有效,在应用程序的其他Session中无效。


重要的事实:

1、一级缓存只在本Session中有效,在应用程序中的其他Session中无效。

2、缓存的范围是Session对象,一旦Session关闭缓存的对象将会永久失效。

3、一级缓存是默认启用的,你不能让他失效。

4、当第一次查询一个实体的时候,会从数据库中获取并储存在和Session关联的一级缓存中。

5、如果我们在同一个Session中再一次查询相同的实体,它将会在缓存中加载SQL查询不会再次被执行。

6、加载的实体可以使用evict()方法被移除。如果使用了这个方法,再次加载相同的实体会发生数据库查询调用。

7、整个的Session中缓存的实体可以通过使用clear()方法移除,这会移除所有的缓存数据。

下面我们使用例子来证实上边提到的问题

一级缓存检索的例子

在这个例子中,我们将在数据库使用hibernate Session中检索DepartmentEntity 对象。我将会检索多次,并且观察SQL日志来查看他们的区别。
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
 
//fetch the department entity from database first time
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
 
//fetch the department entity again
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
 
session.getTransaction().commit();
HibernateUtil.shutdown();
 
Output:
 
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource

我们可以看到第二次查询没有执行SQL语句而是直接加载了实体。

一级缓存在新的Session中检索的例子。

//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
 
Session sessionTemp = HibernateUtil.getSessionFactory().openSession();
sessionTemp.beginTransaction();
try
{
    //fetch the department entity from database first time
    DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
    System.out.println(department.getName());
     
    //fetch the department entity again
    department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
    System.out.println(department.getName());
     
    department = (DepartmentEntity) sessionTemp.load(DepartmentEntity.class, new Integer(1));
    System.out.println(department.getName());
}
finally
{
    session.getTransaction().commit();
    HibernateUtil.shutdown();
     
    sessionTemp.getTransaction().commit();
    HibernateUtil.shutdown();
}
 
Output:
 
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
 
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource

你可以看到,尽管实体已经存在于Session对象中了,但是当使用另一个Session对象sessionTemp的时候依旧会执行数据库查询语句。

在一级缓存中移除缓存对象的例子

尽管我们不能在hibernate中将一级缓存置为无效,但是我们可以在需要的时候移除一些对象。下边是我们使用的两个方法

使用新的Session,实体会被再一次的在数据库中被检索,尽管在其他的Session中实体也已经存在了。
evict()
clear()
这里的evict()方法用于清除缓存中特定的对象,clear()方法用于清除Session范围内所有的缓存的对象。
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
try
{
    //fetch the department entity from database first time
    DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
    System.out.println(department.getName());
     
    //fetch the department entity again
    department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
    System.out.println(department.getName());
     
    session.evict(department);
    //session.clear();
     
    department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
    System.out.println(department.getName());
}
finally
{
    session.getTransaction().commit();
    HibernateUtil.shutdown();
}
         
Output:
         
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
 
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource

很明显,evict()方法移除缓存中的实体对象并且在一次的在数据库中获取对象。

翻译不是很准确,还请大家指正,大家有读不懂的可以参看原文,本人也在学习的过程中

原文地址:http://howtodoinjava.com/2013/07/01/understanding-hibernate-first-level-cache-with-example/

详解Hibernate中的一级缓存

1.前言 在Hibernate中有三级缓存,本篇博客先详细的介绍一下,Hibernate中的一级缓存,也就是Session级别的缓存。  2....
  • ZHOUCHAOQIANG
  • ZHOUCHAOQIANG
  • 2015年08月14日 19:48
  • 6615

Hibernate的一级缓存

Hibernate的一级缓存Hibernate的一级缓存就是指Session缓存。通过查看Session接口的实现类——SessionImpl.java的源码可发现有如下两个类: actionQueu...
  • yerenyuan_pku
  • yerenyuan_pku
  • 2017年04月12日 22:47
  • 1703

hibernate一级缓存和二级缓存的区别

       缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在...
  • defonds
  • defonds
  • 2008年04月20日 13:40
  • 97320

hibernate一级缓存详解

一级缓存的生命周期和session的生命周期一致,当前sessioin一旦关闭,一级缓存就消失,session间不能共享一级缓存的数据,因此一级缓存也叫session级的缓存或事务级缓存。一级缓存只存...
  • zmx729618
  • zmx729618
  • 2016年04月29日 11:27
  • 2002

Hibernate的缓存_一级缓存

什么是缓存 数据存到数据库里面,数据库本身是文件系统,使用流方式操作文件效率不是很高。把数据库存放到内存里面,不需要流方式,可以直接读取内存中的数据,提高了读取效率。 Hibernate缓存 hibe...
  • buhuikanjian
  • buhuikanjian
  • 2016年11月12日 15:36
  • 988

Hibernate旅程(七)Hibernate缓存机制--一级缓存

Hibernate一级缓存 缓存就是你去小卖铺买东西,不用再去生产车间里买东西,当小卖铺倒闭了,也就是session缓存生命周期结束。hibernate一级缓存的声明周期很短,和session的生...
  • lovesummerforever
  • lovesummerforever
  • 2014年03月11日 10:48
  • 4318

Hibernate一级缓存详解

1.Session 级别的缓存,它同session邦定。它的生命周期和session相同。Session消毁,它也同时消毁;管理一级缓存,一级缓存无法取消,用两个方法管理,clear(),evict(...
  • spring123666
  • spring123666
  • 2013年08月22日 12:32
  • 4539

Hibernate一级缓存(基于查询分析)

首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略。我们要将这个跟计算机内存或者cpu的缓存区分开。 ...
  • aiwuzhi12
  • aiwuzhi12
  • 2017年03月10日 22:52
  • 193

用例子理解hibernate的一级缓存

缓存由ORM框架提供以便用户可以获得更快速的访问速度,同时框架本身也减少了数据库查询操作。 hibernate中的一级缓存是默认使用的,使用它你不需要操作任何事情。实际上,你不能强制关闭它。 如果...
  • maoyeqiu
  • maoyeqiu
  • 2015年11月20日 23:44
  • 1107

说说自己对hibernate一级、二级、查询、缓存的理解。

今天面试碰到答不上来。。马上回家查了下,现在写下对hibernate缓存的理解以加深印象。 1、一级缓存 可以简单的理解为session缓存,即同一个session中使用get、load、...
  • u012280292
  • u012280292
  • 2016年03月14日 21:36
  • 1408
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用例子理解hibernate的一级缓存
举报原因:
原因补充:

(最多只允许输入30个字)