Hibernate 一级缓存默认是打开,不需要任何的配置。实际上,你无法强制禁止它的使用。 如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存。总所周知,会话是当我们需要时从会话工厂创建并且一旦会话关闭,缓存就会丢失。相似的,一级缓存与会话对象相关联,在会话存活期间是可用的。相同应用中的不同会话是无法相互访问的。
evict()
方法。如果实体已经使用 evict
下次加载该实体将会再次调用数据库查询clear()
方法移除。它将移除缓存中的所有实体在下面的例子中,将通过 hibernate 会话从数据库检索 Department
实体。多次检索该实体,观察 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
从输出来看,第二次 session.load()
语句并没有执行 select
查询,而是直接加载 department
实体。说明实体对象却是被缓存了。
如果实体已经在一个会话中被获取,在新会话中,该实体将再次从数据库中获取。
//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
从输出可以发现及时 department
实体已经被存储在会话中,但是 sessionTemp
会话还是发出了一条数据库查询语句。说明不同会话之间的缓存是相互不可见的。
虽然无法禁用 hibernate 一级缓存,但是如果需要的话,可以移除该缓存对象。通过使用一下两个方法:
evict()
clear()
evict()
用于移除会话中的指定缓存对象,clear()
方法则用于移除会话中的所有缓存对象。一下代码展示移除一个缓存对象和移除所有缓存对象。
//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()
方法将 department
实体从一级缓存中移除,所以他再次从数据库中获取。
本文内容来自:http://howtodoinjava.com/hibernate/understanding-hibernate-first-level-cache-with-example/。本文只是翻译以及润色
欢迎转载,但请注明本文链接,谢谢你。 2016.9.21 9:08