欢迎学习Hibernate缓存--第一级缓存示例教程。最近,我们学习了[HibernateHQL]、Hibernate architecture以及如何使用[HQL](/community/tutorials/hibernate-query-language-hql-example-tutorialHibernate Query Language(HQL)示例教程
以面向对象的方式触发SQL查询。今天我们来看看Hibernate的一个重要方面--Hibernate缓存 。
Hibernate缓存
休眠缓存中的休眠缓存、休眠缓存、一级缓存在获得快速应用程序性能方面非常有用。缓存背后的想法是减少数据库查询的数量,从而减少应用程序的吞吐时间。Hibernate提供了不同类型的缓存:
1.一级缓存 :Hibernate一级缓存与Session对象关联。默认情况下,Hibernate一级缓存处于启用状态,无法禁用它。然而,Hibernate提供了一些方法,通过这些方法,我们可以从缓存中删除选定的对象或完全清除缓存。会话中缓存的任何对象将对其他会话不可见,并且当会话关闭时,所有缓存的对象也将丢失。 2.二级缓存 :Hibernate二级缓存默认关闭,但我们可以通过配置开启。目前,EHCache和Infinisspan提供了Hibernate二级缓存的实现,我们可以使用它们。我们将在下一篇关于Hibernate缓存的教程中研究这一点。 3.查询缓存 :Hibernate还可以缓存查询的结果集。Hibernate查询缓存不缓存缓存中实际实体的状态;它只缓存值类型的标识符值和结果。因此,它应该始终与二级缓存一起使用。
Hibernate缓存--一级缓存示例
对于我的Hibernate一级缓存示例程序,我使用的配置与HQL Example中的配置相同,您可以签出并配置表,并使用伪数据填充它。让我们先来看看程序,它的输出,然后我们将介绍一些与Hibernate一级缓存相关的要点。HibernateCacheExample.java
1package com.journaldev.hibernate.main;
2
3import org.hibernate.Session;
4import org.hibernate.SessionFactory;
5import org.hibernate.Transaction;
6
7import com.journaldev.hibernate.model.Employee;
8import com.journaldev.hibernate.util.HibernateUtil;
9
10public class HibernateCacheExample {
11
12 public static void main(String[] args) throws InterruptedException {
13
14 SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
15 Session session = sessionFactory.getCurrentSession();
16 Transaction tx = session.beginTransaction();
17
18 //Get employee with id=1
19 Employee emp = (Employee) session.load(Employee.class, new Long(1));
20 printData(emp,1);
21
22 //waiting for sometime to change the data in backend
23 Thread.sleep(10000);
24
25 //Fetch same data again, check logs that no query fired
26 Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
27 printData(emp1,2);
28
29 //Create new session
30 Session newSession = sessionFactory.openSession();
31 //Get employee with id=1, notice the logs for query
32 Employee emp2 = (Employee) newSession.load(Employee.class, new Long(1));
33 printData(emp2,3);
34
35 //START: evict example to remove specific object from hibernate first level cache
36 //Get employee with id=2, first time hence query in logs
37 Employee emp3 = (Employee) session.load(Employee.class, new Long(2));
38 printData(emp3,4);
39
40 //evict the employee object with id=1
41 session.evict(emp);
42 System.out.println("Session Contains Employee with id=1?"+session.contains(emp));
43
44 //since object is removed from first level cache, you will see query in logs
45 Employee emp4 = (Employee) session.load(Employee.class, new Long(1));
46 printData(emp4,5);
47
48 //this object is still present, so you won't see query in logs
49 Employee emp5 = (Employee) session.load(Employee.class, new Long(2));
50 printData(emp5,6);
51 //END: evict example
52
53 //START: clear example to remove everything from first level cache
54 session.clear();
55 Employee emp6 = (Employee) session.load(Employee.class, new Long(1));
56 printData(emp6,7);
57 Employee emp7 = (Employee) session.load(Employee.class, new Long(2));
58 printData(emp7,8);
59
60 System.out.println("Session Contains Employee with id=2?"+session.contains(emp7));
61
62 tx.commit();
63 sessionFactory.close();
64 }
65
66 private static void printData(Employee emp, int count) {
67 System.out.println(count+":: Name="+emp.getName()+", Zipcode="+emp.getAddress().getZipcode());
68 }
69
70}
当我们运行上面的示例时,输出包含大量与Hibernate相关的信息。但我们最感兴趣的是特定于代码的输出和Hibernate为加载数据而触发的查询。输出代码片段如下所示。
1Hibernate Configuration loaded
2Hibernate serviceRegistry created
3Hibernate: 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=?
41:: Name=Pankaj, Zipcode=95129
52:: Name=Pankaj, Zipcode=95129
6Hibernate: 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=?
73:: Name=PankajK, Zipcode=95129
8Hibernate: 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=?
94:: Name=David, Zipcode=95051
10Session Contains Employee with id=1?false
11Hibernate: 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=?
125:: Name=Pankaj, Zipcode=95129
136:: Name=David, Zipcode=95051
14Hibernate: 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=?
157:: Name=Pankaj, Zipcode=95129
16Hibernate: 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=?
178:: Name=David, Zipcode=95051
18Session Contains Employee with id=2?true
Hibernate中的一级缓存要点
从上面的程序中可以得到的关于Hibernate中一级缓存的要点是:
1.默认开启Hibernate一级缓存,无需配置。
2.Hibernate一级缓存是特定于会话的,这就是为什么当我们在同一个会话中获取相同的数据时,不会触发查询,而在其他会话中,会触发查询来加载数据。
3.Hibernate一级缓存可以有旧的值,正如您在上面看到的,我让程序休眠了10秒,在此期间我更新了数据库中的值(名称从Pankaj到PankajK),但它没有在同一会话中反映出来。但在另一次会议上,我们得到了更新的价值。
4.我们可以使用会话evict()
方法从Hibernate一级缓存中移除单个对象。
5.可以使用会话clear()
方法清空缓存,即删除缓存中的所有对象。
6.我们可以使用会话containes()
方法来检查对象是否存在于Hibernate缓存中,如果在缓存中找到该对象,则返回True,否则返回False。
7.由于Hibernate会将所有对象缓存到会话一级缓存中,因此在运行批量查询或批量更新时,需要定期清除缓存,以避免内存问题。
这就是Hibernate缓存和一级缓存的例子,在以后的文章中,我们将研究Hibernate二级缓存-EHCache实现。