Hibernate缓存 - 第一级缓存

194 篇文章 3 订阅
22 篇文章 0 订阅

 

Hibernate缓存 - 第一级缓存

 

欢迎使用Hibernate缓存 - 一级缓存示例教程。最近我们研究了Hibernate架构hibernate映射以及如何使用HQL以面向对象的方式触发SQL查询。今天我们将研究Hibernate的一个重要方面 - Hibernate Cache

 

Hibernate缓存

 

如果正确使用,Hibernate Cache在获得快速应用程序性能方面非常有用。缓存背后的想法是减少数据库查询的数量,从而减少应用程序的吞吐时间。

Hibernate带有不同类型的Cache:

  1. 第一级缓存:Hibernate第一级缓存与Session对象相关联。默认情况下启用Hibernate第一级缓存,无法禁用它。但是,hibernate提供了一些方法,通过这些方法我们可以从缓存中删除所选对象或完全清除缓存。

    会话中缓存的任何对象都不会对其他会话可见,并且会话关闭时,所有缓存的对象也将丢失。

  2. 二级缓存:默认情况下禁用Hibernate二级缓存,但我们可以通过配置启用它。目前EHCache和Infinispan为Hibernate二级缓存提供了实现,我们可以使用它们。我们将在下一个hibernate缓存教程中研究这个问题。
  3. 查询缓存:Hibernate还可以缓存查询的结果集。Hibernate Query Cache不会缓存缓存中实际实体的状态; 它仅缓存标识符值和值类型的结果。所以它应该总是与二级缓存一起使用。

Hibernate缓存 - 第一级缓存示例

对于我的hibernate一级缓存示例程序,我使用与HQL示例中相同的配置,您可以检查并配置表并使用虚拟数据填充它。

让我们首先看看程序,它的输出,然后我们将介绍一些与Hibernate First Level Cache相关的重要事项。

HibernateCacheExample.java


package com.journaldev.hibernate.main;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;

public class HibernateCacheExample {

	public static void main(String[] args) throws InterruptedException {
		
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		//Get employee with id=1
		Employee emp = (Employee) session.load(Employee.class, new Long(1));
		printData(emp,1);
		
		//waiting for sometime to change the data in backend
		Thread.sleep(10000);
		
		//Fetch same data again, check logs that no query fired
		Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
		printData(emp1,2);
		
		//Create new session
		Session newSession = sessionFactory.openSession();
		//Get employee with id=1, notice the logs for query
		Employee emp2 = (Employee) newSession.load(Employee.class, new Long(1));
		printData(emp2,3);
		
		//START: evict example to remove specific object from hibernate first level cache
		//Get employee with id=2, first time hence query in logs
		Employee emp3 = (Employee) session.load(Employee.class, new Long(2));
		printData(emp3,4);
		
		//evict the employee object with id=1
		session.evict(emp);
		System.out.println("Session Contains Employee with id=1?"+session.contains(emp));

		//since object is removed from first level cache, you will see query in logs
		Employee emp4 = (Employee) session.load(Employee.class, new Long(1));
		printData(emp4,5);
		
		//this object is still present, so you won't see query in logs
		Employee emp5 = (Employee) session.load(Employee.class, new Long(2));
		printData(emp5,6);
		//END: evict example
		
		//START: clear example to remove everything from first level cache
		session.clear();
		Employee emp6 = (Employee) session.load(Employee.class, new Long(1));
		printData(emp6,7);
		Employee emp7 = (Employee) session.load(Employee.class, new Long(2));
		printData(emp7,8);
		
		System.out.println("Session Contains Employee with id=2?"+session.contains(emp7));
		
		tx.commit();
		sessionFactory.close();
	}

	private static void printData(Employee emp, int count) {
		System.out.println(count+":: Name="+emp.getName()+", Zipcode="+emp.getAddress().getZipcode());
	}

}

当我们运行上面的例子时,输出包含很多与hibernate相关的信息。但是我们最感兴趣的是我们的代码特定输出和hibernate用来加载数据的查询。输出代码段如下所示。


Hibernate Configuration loaded
Hibernate serviceRegistry created
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
1:: Name=Pankaj, Zipcode=95129
2:: Name=Pankaj, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
3:: Name=PankajK, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
4:: Name=David, Zipcode=95051
Session Contains Employee with id=1?false
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
5:: Name=Pankaj, Zipcode=95129
6:: Name=David, Zipcode=95051
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
7:: Name=Pankaj, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
8:: Name=David, Zipcode=95051
Session Contains Employee with id=2?true

Hibernate重点中的第一级缓存

关于Hibernate中可以从上面的程序派生的第一级缓存的要点是:

  1. 默认情况下启用Hibernate First Level缓存,不需要配置。
  2. Hibernate第一级缓存是特定于会话的,这就是为什么当我们在同一个会话中获取相同的数据时,没有触发查询,而在其他会话查询中则会加载数据。
  3. Hibernate一级缓存可以有旧值,正如你在上面看到的那样,我已经让我的程序进入睡眠状态10秒钟,并且在那段时间我在数据库中更新了值(从Pankaj到PankajK的名称),但它没有反映在同一个会议。但在其他会话中,我们获得了更新的值。
  4. 我们可以使用会话evict()方法从hibernate第一级缓存中删除单个对象。
  5. 我们可以使用会话clear()方法来清除缓存,即从缓存中删除所有对象。
  6. 我们可以使用会话contains()方法检查一个对象是否存在于hibernate缓存中,如果在缓存中找到该对象,则返回true,否则返回false。
  7. 由于hibernate将所有对象缓存到会话第一级缓存中,因此在运行批量查询或批量更新时,必须以特定间隔清除缓存以避免内存问题。

这就是hibernate缓存和第一级缓存的例子,在以后的文章中我们将研究Hibernate二级缓存 - EHCache实现。

 

转载来源:https://www.journaldev.com/2969/hibernate-caching-first-level-cache

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值