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

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

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

服務器之家 - 編程語言 - Java教程 - Hibernate緩存詳解

Hibernate緩存詳解

2020-08-02 12:14MSTK Java教程

本文主要介紹了Hibernate緩存的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧

1. 什么是緩存

數據庫的緩存指的是應用程序和物理數據源之間的數據。即把物理數據源的數據復制到緩存。有了緩存,可以降低應用程序對物理數據源的訪問頻率,從而提高效率。緩存的介質一般是內存,也可以是硬盤。

Hibernate的緩存有三種類型:一級緩存、二級緩存和查詢緩存。

2. 一級緩存

一級緩存即Session緩存,由Session自動進行管理,不需要程序進行干預。一級緩存根據對象的ID進行加載和緩存。如下面的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
@Override
  public void testCache() {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Course c = (Course) session.get(Course.class, 1);
    System.out.println("Name:" + c.getName());
    c = (Course) session.get(Course.class, 1);
    System.out.println("Name:" + c.getName());
    tx.commit();
    session.close();
  }

運行結果:

?
1
2
3
4
5
6
7
8
9
10
11
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Name:計算機原理
Name:計算機原理

第1次查詢時生成了SQL語句,并將查詢出來的對象放在一級緩存里面,第2次查詢時,在一級緩存里面直接找到了這個對象,就不需要再次生成SQL語句了。

再看一個例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
  public void testCache() {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Course c = (Course) session.get(Course.class, 1);
    System.out.println("Name:" + c.getName());
    tx.commit();
    session.close();
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    c = (Course) session.get(Course.class, 1);
    System.out.println("Name:" + c.getName());
    tx.commit();
    session.close();
  }

由于一級緩存是Session級別的緩存,所以Session關閉以后,一級緩存也就不存在了,第2次查詢也要生成SQL語句:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Name:計算機原理
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Name:計算機原理

 3. 二級緩存

二級緩存即SessionFactory緩存,和一級緩存類似,也是根據對象的ID進行加載和緩存,區別就在于一級緩存只在Session內有效,而二級緩存在SessionFactory內有效。在訪問某個ID的對象時,先到一級緩存里面去找,如果沒有找到就到二級緩存里面去找。二級緩存包括EHCache,OSCache,SwarmCache和JBossCache等。這里以EHCache作為例子。

二級緩存需要程序進行管理。首先,配置Maven下載相關的Jar,在pom文件里面添加:

?
1
2
3
4
5
6
7
8
9
10
<dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-ehcache</artifactId>
      <version>4.1.0.Final</version>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>2.8.3</version>
    </dependency>

創建EHCache配置文件ehcache.xml:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ehcache>
  <diskStore path="E:\Eclipse\MyWorkspace\Cache"/>
  <defaultCache
    maxElementsInMemory="10000"
    eternal="true"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    overflowToDisk="true"
  />
  <cache name="com.hzhi.course.entity.Course"
    maxElementsInMemory="10000"
    eternal="true"
    timeToIdleSeconds="300"
    timeToLiveSeconds="600"
    overflowToDisk="true"
  />
</ehcache>

defaultCache是默認的設置,下面一個cache指明了對哪一個類進行二級緩存。里面設置了最大緩存的對象數量,是否永久有效、最大空閑秒數、最大生存秒數、內存滿時是否寫到硬盤,寫到硬盤的路徑等等。

修改需要緩存的類的hbm文件:

?
1
2
3
4
<class name="com.hzhi.course.entity.Course" table="clas">
   <cache usage="read-only"/>
       ......
 </class>

usage設置了并發訪問策略,一般設置成read-only。

修改applicationContext.xml中的SessionFactory的配置,增加二級緩存的一些屬性:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- SessionFactory -->
   <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" >
      <ref local="dataSource"/>
    </property>
    <!-- 配置Hibernate的屬性 -->
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.format_sql">true</prop>
        <prop key="hibernate.connection.isolation">8</prop>
        <!-- 二級緩存 -->
        <prop key="hibernate.cache.use_second_level_cache">false</prop>
        <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>       
        <prop key="hibernate.cache.provider_configuration_file_resource_path">WEB-INF/ehcache.xml</prop>       
      </props>
    </property>
     ......
   </bean>

運行下面的例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
  public void testCache() {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Course c = (Course) session.get(Course.class, 1);
    System.out.println("Name:" + c.getName());
    tx.commit();
    session.close();
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    c = (Course) session.get(Course.class, 1);
    System.out.println("Name:" + c.getName());
    tx.commit();
    session.close();
  }

結果:

?
1
2
3
4
5
6
7
8
9
10
11
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Name:計算機原理
Name:計算機原理

雖然關閉了Session,但是二級緩存仍然存在,所以只生成了一次SQL語句。

下面的例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
  public void testCache() {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Query query = session.createQuery("from Course");
    Iterator iter = query.iterate();
    while(iter.hasNext()){
        System.out.println(((Course)iter.next()).getName());
    }
    tx.commit();
    session.close();
    
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    query = session.createQuery("from Course");
    iter = query.iterate();
    while(iter.hasNext()){
        System.out.println(((Course)iter.next()).getName());
    }
    tx.commit();
    session.close();
  }

結果:

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Hibernate:
  select
    course0_.ID as col_0_0_
  from
    clas course0_
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
計算機原理
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
計算機網絡
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
數據庫原理
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
C語言
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
大學英語A
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Java
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Linux
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
高等數學
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
語文
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
大學物理
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
軟件工程
Hibernate:
  select
    course0_.ID as col_0_0_
  from
    clas course0_
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程

當使用Query的list()方法時,只生成一次SQL語句查詢出所有的對象,使用iterate()方法時,會先得到所有對象的ID,然后根據每個ID生成一次SQL語句查詢。第二個Session里面使用的也是iterate()方法,首先生成一次SQL語句,得到ID,然后根據ID查找對象,由于開啟了二級緩存,在二級緩存里面找到了對象,所以就直接輸出了,并沒有再根據每個ID生成SQL語句。

不論是一級緩存還是二級緩存,都只能緩存對象,不能緩存屬性的值。下面的例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
  public void testCache() {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Query query = session.createQuery("select c.name from Course c"); 
    List<String> names = query.list();
    for(Iterator iter = names.iterator(); iter.hasNext();){
      String name = (String) iter.next();
      System.out.println(name);
    }
    System.out.println("----------");
    query = session.createQuery("select c.name from Course c"); 
    names = query.list();
    for(Iterator iter = names.iterator(); iter.hasNext();){
      String name = (String) iter.next();
      System.out.println(name);
    }
    System.out.println("----------");
    tx.commit();
    session.close();
  }

運行結果:

?
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
Hibernate:
  select
    course0_.NAME as col_0_0_
  from
    clas course0_
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------
Hibernate:
  select
    course0_.NAME as col_0_0_
  from
    clas course0_
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------

雖然開啟了二級緩存,但是查詢的結果不是對象,是屬性,所以并沒有緩存,第2次查詢仍然生成了查詢語句。要解決這個問題,就需要查詢緩存。

3. 查詢緩存

在配置了二級緩存的基礎上,可以設置查詢緩存,在SessionFactory的設置里面加上一行:

<prop key="hibernate.cache.use_query_cache">true</prop>

即打開了查詢緩存。查詢緩存也是SessionFactory級別的緩存,在整個SessionFactory里面都是有效的。

關閉二級緩存,運行下面的例子,在Query后面添加setCacheable(true)打開查詢緩存:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
  public void testCache() {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Query query = session.createQuery("select c.name from Course c");
    query.setCacheable(true);
    List<String> names = query.list();
    for(Iterator iter = names.iterator(); iter.hasNext();){
      String name = (String) iter.next();
      System.out.println(name);
    }
    System.out.println("----------");
    query = session.createQuery("select c.name from Course c");
    query.setCacheable(true);
    names = query.list();
    for(Iterator iter = names.iterator(); iter.hasNext();){
      String name = (String) iter.next();
      System.out.println(name);
    }
    System.out.println("----------");
    tx.commit();
    session.close();
  }

結果:

?
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
Hibernate:
  select
    course0_.NAME as col_0_0_
  from
    clas course0_
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------

由于兩次查詢的HQL語句是一致的,所以只生成一次SQL語句。但是如果把第二次查詢改一下:

?
1
2
3
4
5
6
7
8
9
System.out.println("----------");
    query = session.createQuery("select c.name from Course c where c.id > 5");
    query.setCacheable(true);
    names = query.list();
    for(Iterator iter = names.iterator(); iter.hasNext();){
      String name = (String) iter.next();
      System.out.println(name);
    }
    System.out.println("----------");

結果:

?
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
Hibernate:
  select
    course0_.NAME as col_0_0_
  from
    clas course0_
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------
Hibernate:
  select
    course0_.NAME as col_0_0_
  from
    clas course0_
  where
    course0_.ID>5
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------

由于HQL語句變了,所以第二次也生成了SQL語句。

查詢緩存可以緩存屬性,也可以緩存對象,但是當緩存對象時,只緩存對象的ID,不會緩存整個對象。下面的例子:

?
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
@Override
  public void testCache() {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Query query = session.createQuery("from Course");
    query.setCacheable(true);
    List<Course> list = query.list();
    for (int i=0; i<list.size(); i++){
      System.out.println(list.get(i).getName());
    }
    System.out.println("----------");
    tx.commit();
    session.close();
    session = sessionFactory.openSession();
    tx = session.beginTransaction();   
    query = session.createQuery("from Course");
    query.setCacheable(true);
    list = query.list();
    for (int i=0; i<list.size(); i++){
      System.out.println(list.get(i).getName());
    }
    System.out.println("----------");
    tx.commit();
    session.close();
  }

 結果:

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Hibernate:
  select
    course0_.ID as ID0_,
    course0_.NAME as NAME0_,
    course0_.COMMENT as COMMENT0_
  from
    clas course0_
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
Hibernate:
  select
    course0_.ID as ID0_0_,
    course0_.NAME as NAME0_0_,
    course0_.COMMENT as COMMENT0_0_
  from
    clas course0_
  where
    course0_.ID=?
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------

由于開了查詢緩存,沒有開二級緩存,雖然使用的是list()方法一次查詢出了所有的對象,但是查詢緩存只緩存了對象ID,沒有緩存整個對象。所以在第2個Session里面"from Course"這個HQL由于和前面的相同,并沒有生成SQL語句,但是由于沒有開二級緩存,沒有緩存整個對象,只能根據每個ID去生成一次SQL語句。雖然兩次用的都是list()方法,但是第一次是生成SQL語句去一次查詢出所有的對象,而第二次是根據查詢緩存里面的ID一個一個的生成SQL語句。

如果同時打開查詢緩存和二級緩存,第2個Session里面就不用再根據ID去生成SQL語句了:

?
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
Hibernate:
  select
    course0_.ID as ID0_,
    course0_.NAME as NAME0_,
    course0_.COMMENT as COMMENT0_
  from
    clas course0_
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------
計算機原理
計算機網絡
數據庫原理
C語言
大學英語A
Java
Linux
高等數學
語文
大學物理
軟件工程
----------

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!

原文鏈接:http://www.cnblogs.com/mstk/p/6363351.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91av爱爱 | 草妞视频| 国产91久久久 | av成人免费在线观看 | 日本中文视频 | 成年免费网站 | 欧美爱爱一区二区 | 毛片一区二区三区 | 久久国产精 | 久久久久久片 | 99精品国产一区二区三区 | 91网视频在线观看 | 91九色视频观看 | 毛片视频网站在线观看 | 国产乱色精品成人免费视频 | 国产成人强伦免费视频网站 | 欧美性色黄大片www 成人免费网站在线观看 | 国产成人精品免费视频大全办公室 | 亚洲精品无码不卡在线播放he | 暴力强行进如hdxxx | 久草在线视频新 | 成人免费观看在线视频 | 色婷婷tv | 97伦理 | 一级黄色大片在线观看 | 91情侣在线偷精品国产 | 羞羞的动漫在线观看 | 在线天堂中文字幕 | 午夜久久久精品一区二区三区 | 国产精品伊人久久 | 欧美日韩中文字幕在线视频 | 日本一区二区精品 | 欧美1区2区在线观看 | 久草在线高清 | 在线观看一二三 | 涩涩99| 亚洲天堂午夜 | 久久久久久久不卡 | 精品在线视频观看 | 日日草天天干 | 在线a毛片免费视频观看 |