激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - hibernate查詢緩存詳細分析

hibernate查詢緩存詳細分析

2020-12-29 15:22動力節點 Java教程

這篇文章主要介紹了hibernate查詢緩存詳細分析,包括查詢緩存配置方法及關閉二級緩存的詳細介紹,需要的朋友參考下本文吧

 一、查詢緩存配置

1、在hibernate.cfg.xml中加入查詢緩存的策略,  <propertyname="hibernate.cache.use_query_cache">true</property>      啟用查詢緩存的策略,默認是false。 

二、關閉二級緩存,采用query.list()查詢普通屬性

代碼如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public voidtestCache1() {
  Session session = null;
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   Listnames = session.createQuery("select s.name from Student s")
       .setCacheable(true)
       .list();
   for (int i=0;i<names.size(); i++) {
   Stringname = (String)names.get(i);
   System.out.println(name);
   }
   System.out.println("-------------------------------------------------------");
   //不會發出查詢語句,因為啟用查詢緩存
   names= session.createQuery("select s.name from Student s")
      .setCacheable(true)
      .list();
   for (int i=0;i<names.size(); i++) {
   Stringname = (String)names.get(i);
   System.out.println(name);
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
 }

我們可以看到控制臺輸出語句,僅輸出一次:Hibernate: select student0_.name as col_0_0_ fromt_student student0_ 

由此可知,我們開啟了查詢緩存,第一次進行查詢的時候,已經把結果放到querycache中,當第二次再次做出相同的查詢的時候,就不再向數據庫發重復的sql語句了。

三、關閉二級緩存,啟用查詢緩存,采用query.list()查詢普通屬性

代碼就如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public voidtestCache2() {
  Sessionsession = null;
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   Listnames = session.createQuery("select s.name from Student s")
       .setCacheable(true)
       .list();
   for (int i=0;i<names.size(); i++) {
   Stringname = (String)names.get(i);
   System.out.println(name);
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
  System.out.println("-------------------------------------------------------");
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   //不會發出查詢語句,因為查詢緩存和session的生命周期沒有關系
   Listnames = session.createQuery("select s.name from Student s")
       .setCacheable(true)
       .list();
   for (int i=0;i<names.size(); i++) {
   Stringname = (String)names.get(i);
   System.out.println(name);
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }  
 }

運行結果如下所示。

控制臺打印結果:

select student0_.name as col_0_0_ fromt_student student0_
班級0的學生0
班級0的學生1
班級0的學生2
班級0的學生3
班級0的學生4
班級0的學生5…

我們可以看出,同樣,只打印一次查詢語句,如果沒有開啟查詢緩存的話,并且關閉二級緩存的情況下,還會去數據庫再查詢一遍,而我們的程序中沒有再去重復的去數據庫中查詢的原因是,當開啟query緩存的時候,查詢緩存的生命周期與session無關。

四、關閉二級緩存,開啟查詢,采用query.iterate()查詢普通屬性

代碼如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public voidtestCache3() {
  Sessionsession = null;
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   Iteratoriter = session.createQuery("select s.name from Student s")
       .setCacheable(true)
       .iterate();
   while(iter.hasNext()){
   Stringname = (String)iter.next();
   System.out.println(name);
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
  System.out.println("-------------------------------------------------------");
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   //會發出查詢語句,query.iterate()查詢普通屬性它不會使用查詢緩存
   //查詢緩存只對query.list()起作用
   Iteratoriter = session.createQuery("select s.name from Student s")
      .setCacheable(true)
      .iterate();
   while(iter.hasNext()){
   Stringname = (String)iter.next();
   System.out.println(name);
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
  
 }

顯控制臺顯示結果打印了兩次sql語句。

-------------------------------------------------------

?
1
Hibernate: select student0_.name as col_0_0_from t_student student0_

根據這樣的結果我們發現,quer.iterate()查詢普通屬性它是不會使用查詢緩存,查詢緩存只對query.list()起作用。

五、關閉二級緩存,關閉查詢緩存,采用query.list()查詢實體

代碼如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public voidtestCache4() {
  Sessionsession = null;
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   List students =session.createQuery("select s from Student s")
       .list();
   for (int i=0;i<students.size(); i++) {
   Studentstudnet = (Student)students.get(i);
   System.out.println(studnet.getName());
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
  System.out.println("-------------------------------------------------------");
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   //會發出查詢語句,默認query.list()每次執行都會發出查詢語句
   List students =session.createQuery("select s from Student s")
       .list();
   for (int i=0;i<students.size(); i++) {
   Studentstudnet = (Student)students.get(i);
   System.out.println(studnet.getName());
   }
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
 }

   顯示結果如下所示。

控制臺上打印兩次sql語句。

?
1
Hibernate:select student0_.id as id0_, student0_.name as name0_, student0_.classesid asclassesid0_ from t_student student0_

班級0的學生0
班級0的學生1
班級0的學生2
班級0的學生3
班級0的學生4

由此可知,不開啟查詢緩存,默認query.list每次執行都會發出查詢語句。

六、關閉二級緩存,開啟查詢緩存,采用query.list()查詢實體

代碼如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Session session = null;
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   Liststudents = session.createQuery("select s from Student s")
       .setCacheable(true)
       .list();
   for (int i=0;i<students.size(); i++) {
   Studentstudnet = (Student)students.get(i);
   System.out.println(studnet.getName());
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
  System.out.println("-------------------------------------------------------");
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   
   //會發出n條查詢語句,因為開啟了查詢緩存,關閉了二級緩存,那么查詢緩存就會緩存實體對象的id
   //第二次執行query.list(),將查詢緩存中的id依次取出,分別到一級緩存和二級緩存中查詢相應的實體
   //對象,如果存在就使用緩存中的實體對象,否則根據id發出查詢學生的語句
   Liststudents = session.createQuery("select s from Student s")
       .setCacheable(true)
       .list();
   for (int i=0;i<students.size(); i++) {
   Studentstudnet = (Student)students.get(i);
   System.out.println(studnet.getName());
   }
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }

控制臺打印sql如下圖所示。

hibernate查詢緩存詳細分析

在第一次查詢的時候,發出一條sql語句查詢出結果,因為我們開啟了查詢緩存,會把第一次查詢出的實體結果集的id放到查詢緩存中,第二次再次執行query.list()的時候,會把id拿出來,到相應的緩存去找,因為是跨session,在二級緩存中找不到,所以每次都會發出查詢語句,二級緩存中不存在,有多少個id就會發出查詢語句多少次。 

七、開啟二級緩存,開啟查詢緩存,采用query.list()查詢實體

代碼如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
 * 開啟查詢,開啟二級緩存,采用query.list()查詢實體
 *
 * 在兩個session中發query.list()查詢
 */
 public voidtestCache6() {
  Sessionsession = null;
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   Liststudents = session.createQuery("select s from Student s")
       .setCacheable(true)
       .list();
   for (int i=0;i<students.size(); i++) {
   Studentstudnet = (Student)students.get(i);
   System.out.println(studnet.getName());
   }
   session.getTransaction().commit();
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
  System.out.println("-------------------------------------------------------");
  try {
   session= HibernateUtils.getSession();
   session.beginTransaction();
   
   //不再發出查詢語句,因為配置了二級緩存和查詢緩存
   Liststudents = session.createQuery("select s from Student s")
       .setCacheable(true)
       .list();
   for (int i=0;i<students.size(); i++) {
   Studentstudnet = (Student)students.get(i);
   System.out.println(studnet.getName());
   }
  }catch(Exceptione) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }
 }

結果如下所示

?
1
Hibernate: select student0_.id as id0_,student0_.name as name0_, student0_.classesid as classesid0_ from t_studentstudent0_

只發出一次sql請求,當我們第一次執行query.list()會放到二級緩存中,和query緩存中。當我們第一次執行查詢時,會找到相應的id到緩存中查找,在二級緩存中存在,則直接從二級緩存中取出數據,不再向數據庫中發出sql語句。

八、查詢緩存總結

查詢緩存是緩存普通屬性結果集的,對實體對象的結果集會緩存id。查詢緩存的生命周期,當關聯的表發生修改時,查詢緩存的生命周期結束。

而開啟緩存的時候,我們就要去維護緩存,如果緩存和內存中的數據不一致的話,和數據不同步,可能給用戶顯示的是臟數據了。所以根據需要使用緩存機制。

總結

以上所述是小編給大家介紹的hibernate查詢緩存詳細分析,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

原文鏈接:http://blog.sina.com.cn/s/blog_9c6852670102wvhj.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 精品一区二区三区在线视频 | 久久亚洲精品国产一区 | 久久国产成人午夜av浪潮 | 国产小视频在线观看 | xnxx 日本19 | 久久99精品久久久久久秒播蜜臀 | aaaaaaa毛片 | 国产午夜精品一区二区三区不卡 | 亚洲精品aⅴ中文字幕乱码 欧美囗交 | 色偷偷一区 | 九九热在线视频观看这里只有精品 | 日日操夜夜操视频 | 欧美日韩在线视频观看 | 久产久精品 | 中文字幕在线播放第一页 | 草逼一区 | 欧美三级欧美成人高清www | 羞羞视频入口 | 久久99国产伦子精品免费 | 九九视频在线观看黄 | 欧美va亚洲| 斗罗破苍穹在线观看免费完整观看 | 黄色片小说 | 欧美级毛片 | 精品国产一区二区三区久久久蜜月 | 男女羞羞在线观看 | 国产亚洲精品久久久久久网站 | 神秘电影91 | 免费a级黄色毛片 | 国产精品视频一区二区三区综合 | 黄色网址免费在线播放 | 日韩毛片一区二区三区 | 男女无套免费视频 | 久久97超碰 | 色黄视频网站 | 黄色av电影在线播放 | 亚洲一区二区中文字幕在线观看 | 色玖玖综合| 欧美福利视频一区二区 | 欧美一级黄 | 男女羞羞在线观看 |