mybatis入門教程(九)------mybatis緩存

9. Mybatis 緩存

   正如大多數持久層框架同樣,MyBatis 一樣提供了一級緩存二級緩存的支持java

1. 一級緩存: 基於PerpetualCache 的 HashMap本地緩存,其存儲做用域爲 Session,當 Session flush 或 close 以後,該Session中的全部 Cache 就將清空。
2. 二級緩存與一級緩存其機制相同,默認也是採用 PerpetualCache,HashMap存儲,不一樣在於其存儲做用域爲 Mapper(Namespace),而且可自定義存儲源,如 Ehcache。
3. 對於緩存數據更新機制,當某一個做用域(一級緩存Session/二級緩存Namespaces)的進行了 C/U/D 操做後,默認該做用域下全部 select 中的緩存將被clear。


9.1 Mybatis的一級緩存


9.1.1  數據表準備

/*用戶表*/
drop table if exists user;
create table user(
	id int primary key auto_increment,
	username varchar(50) unique,
	password varchar(100),
	nickname varchar(50),
	salt varchar(100),
	locked boolean
)engine=InnqDB default charset=utf8;


9.1.2  User實體類準備

package com.mscncn.batis.model;


public class User {
	private int id;
	private int age;
	private String userName;
	private String userAddress;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserAddress() {
		return userAddress;
	}
	public void setUserAddress(String userAddress) {
		this.userAddress = userAddress;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

9.1.3 UserMapper.java

public interface UserMapper {
	public User getUserById(int id);
}

9.1.4 UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper 
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<!-- 這裏namespace必須是PostsMapper接口的路徑,否則要運行的時候要報錯 「is not known to the MapperRegistry」--> 
<mapper namespace="com.mscncn.batis.mapper.UserMapper"> 
    <!-- 這兒的resultType是配置在mybatis-config.xml中得別名 -->
    <select id="getUserById" parameterType="int" resultType="User">
    		select * from user where id=#{id}
    </select>
</mapper>

9.1.5 測試

@Test 
    public void testgetUserById() { 
       SqlSession sqlSession = sqlSessionFactory.openSession(); 
       try { 
    	   		UserMapper mapper = sqlSession.getMapper(UserMapper.class); 
    	   		//注意,重寫User的toString方法
    	   		User u1=mapper.getUserById(1);
    	   		System.out.println(u1);
    	   		User u2=mapper.getUserById(1);
    	   		System.out.println(u2);
           sqlSession.commit();//這裏必定要提交,否則數據進不去數據庫中 
       } finally { 
           sqlSession.close(); 
       } 
    }


9.1.6 測試結果


   從以上結果中能夠看出,兩次調用getUserById方法,可是隻有一次查詢數據庫的過程,這種現象產生的緣由就是mybatis的一級緩存,而且一級緩存是默認開啓的。算法


9.2  Mybatis的二級緩存


9.2.1 沒有開啓Mybatis二級緩存以前,測試

 @Test 
    public void testCache2() { 
       SqlSession sqlSession = sqlSessionFactory.openSession(); 
       SqlSession sqlSession2 = sqlSessionFactory.openSession(); 
       try { 
    	   		UserMapper mapper = sqlSession.getMapper(UserMapper.class); 
    	   		UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); 
    	   		//注意,重寫User的toString方法
    	   		User u1=mapper.getUserById(1);
    	   		System.out.println(u1);
    	   		User u2=mapper2.getUserById(1);
    	   		System.out.println(u2);
           sqlSession.commit();//這裏必定要提交,否則數據進不去數據庫中 
       } finally { 
           sqlSession.close(); 
       } 
    }


  測試結果:sql

  兩個session,分別查詢id爲1 的 User ,那麼mybatis與數據庫交互了兩次,這樣說明mybatis如今沒有開啓二級緩存,須要咱們手動的開啓。數據庫


9.2.2 User.java

    實體類實現可序列化接口:
apache

public class User implements Serializable {...}

    若是實體類不實現可序列化接口,使用二級緩存,那麼會報下列異常:
緩存

org.apache.ibatis.cache.CacheException: Error serializing object.  Cause: java.io.NotSerializableException:

   

9.2.3 Mybatis 配置文件

    默認配置:
session

<settings>
<setting name="cacheEnabled" value="true"/>
</settings>

 必須開啓緩存配置,才能使用mybatis的二級緩存,否則不能使用mybatis


9.2.4 Mybatis二級緩存測試

@Test 
    public void testCache2() { 
    	SqlSession sqlSession = sqlSessionFactory.openSession(); 
        SqlSession sqlSession2 = sqlSessionFactory.openSession(); 
        try { 
     	   		UserMapper mapper = sqlSession.getMapper(UserMapper.class); 
     	   		UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); 
     	   		//注意,重寫User的toString方法
     	   		User u1=mapper.getUserById(1);
     	   		sqlSession.commit();
     	   		System.out.println(u1);
     	   		User u2=mapper2.getUserById(1);
     	   		System.out.println(u2);
            sqlSession.commit();//這裏必定要提交,否則數據進不去數據庫中 
        } finally { 
            sqlSession.close(); 
        } 
    }

   這兒須要注意,必須使用的是兩個不一樣的session,而且第一個session必須提交才能使用二級緩存(二級緩存必須提交前面的session,如今尚未找到緣由)app

9.2.5 測試結果

9.3 總結

  mybatis 一級緩存:默認開啓
框架

  1. 必須同一個session,若是session對象已經close()過了就不能用了

  2. 查詢條件必須一致

  3. 沒有執行過session.cleanCache();清理緩存

  4. 沒有執行過增刪改操做(這些操做都會清理緩存) 

 mybatis 二級緩存: 

mybatis-config.xml 中默認配置

  <settings> 
        <setting name="cacheEnabled" value="true" /> 
  </settings>

 必須手動開啓在Mapper.xml中添加

 <cache/> 有默認的參數值

<cache />
<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper 
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<!-- 這裏namespace必須是PostsMapper接口的路徑,否則要運行的時候要報錯 「is not known to the MapperRegistry」--> 
<mapper namespace="com.mscncn.batis.mapper.UserMapper"> 
	<cache />
    <!-- 這兒的resultType是配置在mybatis-config.xml中得別名 -->
    <select id="getUserById" parameterType="int" resultType="User">
    		select * from user where id=#{id}
    </select>
</mapper>

1. 映射語句文件中的全部select語句將會被緩存。 

2. 映射語句文件中的全部insert,update和delete語句會刷新緩存。 

3. 緩存會使用Least Recently Used(LRU,最近最少使用的)算法來收回。 

4. 緩存會根據指定的時間間隔來刷新。 

5. 緩存會存儲1024個對象


<cache 

eviction="FIFO"  //回收策略爲先進先出

flushInterval="60000" //自動刷新時間60s

size="512" //最多緩存512個引用對象

readOnly="true"/> //只讀

相關文章
相關標籤/搜索