Hibernate缓存

一、Hibernate缓存概述

Hibernate中提供两个级别的缓存,一级缓存和二级缓存。

1.一级缓存是Session级别的缓存,它属于事物范围的缓存,一级缓存有hibernate进行管理。

2.二级缓存是sessionFactory级别的缓存,它属于进程范围的缓存,二级缓存又可分为"内置缓存"和"外置缓存",内置缓存:是hibernate在创建sessionFactory时会加载.hbn.xml文件并会在内存中初始化一些默认的sql语句,该内置缓存是只读的;外置缓存(二级缓存),默认sessionFactory不会启动这个缓存插件,外置缓存中的数据是数据库中数据的复制,存储的物理介质可以是内存或者硬盘。

二、Hibernate一级缓存

session的缓存有两大作用:

1.减少访问数据库的频率。

2.保证数据库中的相关记录与缓存中的相关对象保持一致。

Session根据脏对象的最新属性执行相关SQL语句,从而保证了数据库中的相关记录与缓存中的响应对象的同步,默认在如下时间点,session会清理缓存:

1.应用程序调用Transaction的commit()方法时,commit()会先清理缓存,再向数据库提交事务。

2.应用程序执行一些查询操作,缓存中的持久化对象的属性发生变化时。

3.显式调用Session的flush()方法。

Session提供了两个管理缓存的方法:

1.evict(Object obj);从缓存中清除特定持久化对象。

2.clear();清空缓存中,所有持久化对象。

三、Hibernate二级缓存

1. 使用 Hibernate 二级缓存的步骤:

1). 加入二级缓存插件的 jar 包及配置文件:

I. 复制 \hibernate-release-4.2.4.Final\lib\optional\ehcache\*.jar 到当前 Hibrenate 应用的类路径下.
II. 复制 hibernate-release-4.2.4.Final\project\etc\ehcachexml 到当前 WEB 应用的类路径下

2). 配置 hibernate.cfg.xml下载

I. 配置启用 hibernate 的二级缓存
true

II. 配置hibernate二级缓存使用的产品
org.hibernate.cache.ehcache.EhCacheRegionFactory

III. 配置对哪些类使用 hibernate 的二级缓存


实际上也可以在 .hbm.xml 文件中配置对哪些类使用二级缓存, 及二级缓存的策略是什么.下载

2). 集合级别的二级缓存的配置

I. 配置对集合使用二级缓存

也可以在 .hbm.xml 文件中进行配置







II. 注意: 还需要配置集合中的元素对应的持久化类也使用二级缓存! 否则将会多出 n 条 SQL 语句.

3). ehcache 的 配置文件: ehcache.xml

4). 查询缓存: 默认情况下, 设置的缓存对 HQL 及 QBC 查询时无效的, 但可以通过以下方式使其是有效的

I. 在 hibernate 配置文件中声明开启查询缓存

true

II. 调用 Query 或 Criteria 的 setCacheable(true) 方法
@Test
public void testQueryCache(){
Query query = session.createQuery("FROM Employee");
query.setCacheable(true);

List emps = query.list();
System.out.println(emps.size());

emps = query.list();
System.out.println(emps.size());

Criteria criteria = session.createCriteria(Employee.class);
criteria.setCacheable(true);
}
III. 查询缓存依赖于二级缓存(使用查询缓存的前提是配置hibernate二级缓存)

示例:下载

Department.java类:

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
package  com.atguigu.hibernate.entities;
 
import  java.util.HashSet;
import  java.util.Set;
 
public  class  Department {
 
     private  Integer id;
     private  String name;
     
     private  Set emps =  new  HashSet<>();
 
     public  Integer getId() {
         return  id;
     }
 
     public  void  setId(Integer id) {
         this .id = id;
     }
 
     public  String getName() {
         return  name;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  Set getEmps() {
         return  emps;
     }
 
     public  void  setEmps(Set emps) {
         this .emps = emps;
     }
 
     @Override
     public  String toString() {
         return  "Department [id="  + id +  "]" ;
     }
     
}

  Department.hbm.xml文件配置:下载

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
"1.0" ?>
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
 
 
     < class  name= "com.atguigu.hibernate.entities.Department"  table= "GG_DEPARTMENT" >
         
         "id"  type= "java.lang.Integer" >
             "ID"  />
             class = "native"  />
        
     
         "name"  type= "java.lang.String" >
             "NAME"  />
        
         
         "emps"  table= "GG_EMPLOYEE"  inverse= "true"  lazy= "true" >
            
                 "DEPT_ID"  />
            
             class = "com.atguigu.hibernate.entities.Employee"  />
        
         
     class >

  Employee.java类:

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
package  com.atguigu.hibernate.entities;
 
public  class  Employee {
 
     private  Integer id;
     private  String name;
     private  float  salary;
     private  String email;
     
     private  Department dept;
 
     public  Integer getId() {
         return  id;
     }
 
     public  void  setId(Integer id) {
         this .id = id;
     }
 
     public  String getName() {
         return  name;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  float  getSalary() {
         return  salary;
     }
 
     public  void  setSalary( float  salary) {
         this .salary = salary;
     }
 
     public  String getEmail() {
         return  email;
     }
 
     public  void  setEmail(String email) {
         this .email = email;
     }
 
     public  Department getDept() {
         return  dept;
     }
 
     public  void  setDept(Department dept) {
         this .dept = dept;
     }
 
     @Override
     public  String toString() {
         return  "Employee [id="  + id +  "]" ;
     }
 
     public  Employee(String email,  float  salary, Department dept) {
         super ();
         this .salary = salary;
         this .email = email;
         this .dept = dept;
     }
     
     public  Employee() {
         // TODO Auto-generated constructor stub
     }
     
}

  Employee.hbm.xml文件配置:

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
"1.0" ?>
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
 
 
     < class  name= "com.atguigu.hibernate.entities.Employee"  table= "GG_EMPLOYEE" >
         
        
             
         "id"  type= "java.lang.Integer" >
             "ID"  />
             class = "native"  />
        
     
         "name"  type= "java.lang.String" >
             "NAME"  />
        
         
         "salary"  type= "float" >
             "SALARY"  />
        
         
         "email"  type= "java.lang.String" >
             "EMAIL"  />
        
         
         "dept"  class = "com.atguigu.hibernate.entities.Department" >
             "DEPT_ID"  />
        
         
     class >
     
     "salaryEmps" > :minSal AND e.salary < :maxSal]]>
     

  hibernate.cfg.xml文件的配置:

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
"1.0"  encoding= "UTF-8" ?>
         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
    
     
        
         "connection.username" >scott
         "connection.password" >java
         "connection.driver_class" >oracle.jdbc.driver.OracleDriver
         "connection.url" >jdbc:oracle:thin: @localhost : 1521 :orcl
 
        
        
         "dialect" >org.hibernate.dialect.Oracle10gDialect
     
        
         "show_sql" > true
     
        
         "format_sql" > true
     
        
         "hbm2ddl.auto" >update
         
        
         "connection.isolation" > 2
         
        
         "use_identifier_rollback" > true
         
        
        
         
        
         "hibernate.jdbc.fetch_size" > 100
         
        
         "jdbc.batch_size" > 30
         
        
         "cache.use_second_level_cache" > true
         
        
         "hibernate.cache.region.factory_class" >org.hibernate.cache.ehcache.EhCacheRegionFactory
         
        
         "cache.use_query_cache" > true
         
        
         "current_session_context_class" >thread
         
        
         "com/atguigu/hibernate/entities/Department.hbm.xml" />
         "com/atguigu/hibernate/entities/Employee.hbm.xml" />
         
         < class -cache usage= "read-write"  class = "com.atguigu.hibernate.entities.Employee" />
         < class -cache usage= "read-write"  class = "com.atguigu.hibernate.entities.Department" />
         "read-write"  collection= "com.atguigu.hibernate.entities.Department.emps" />
    

  ecache.xml文件的配置及方法说明:

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
 
    
         
     "d:\\tempDirectory" />
 
 
    
        
    
         maxElementsInMemory= "10000"
         eternal= "false"
         timeToIdleSeconds= "120"
         timeToLiveSeconds= "120"
         overflowToDisk= "true"
         />
 
    
    
     "com.atguigu.hibernate.entities.Employee"
         maxElementsInMemory= "1"
         eternal= "false"
         timeToIdleSeconds= "300"
         timeToLiveSeconds= "600"
         overflowToDisk= "true"
         />
 
     "com.atguigu.hibernate.entities.Department.emps"
         maxElementsInMemory= "1000"
         eternal= "true"
         timeToIdleSeconds= "0"
         timeToLiveSeconds= "0"
         overflowToDisk= "false"
         />
 

  二级缓存的查询缓存的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
     public  void  testQueryCache(){
         Query query = session.createQuery( "FROM Employee" );
         query.setCacheable( true );
         
         List emps = query.list();
         System.out.println(emps.size());
         
         emps = query.list();
         System.out.println(emps.size());
         
         Criteria criteria = session.createCriteria(Employee. class );
         criteria.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
@Test
     public  void  testQueryIterate(){
         Department dept = (Department) session.get(Department. class 70 );
         System.out.println(dept.getName());
         System.out.println(dept.getEmps().size());
         
         Query query = session.createQuery( "FROM Employee e WHERE e.dept.id = 80" );
         /**
          * 使用query.list()方法会查询Employee所有字段,并用反射机制组装成List 对象
          */
//      List emps = query.list();
//      System.out.println(emps.size());
         /**
          * query.iterator()只查id字段,根据id从二级缓存中找对象,如果二级中有则组装,二级缓存没有再从数据库中找
          * 不用在内存中生成一批Employee对象装配集合了,
          * 使用这种方法需要:

你可能感兴趣的:(hibernate,多数据源,数据库,框架,缓存)