正如大多數持久層框架同樣,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。
/*用戶表*/ 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;
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; } }
public interface UserMapper { public User getUserById(int id); }
<?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>
@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(); } }
從以上結果中能夠看出,兩次調用getUserById方法,可是隻有一次查詢數據庫的過程,這種現象產生的緣由就是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如今沒有開啓二級緩存,須要咱們手動的開啓。數據庫
實體類實現可序列化接口:
apache
public class User implements Serializable {...}
若是實體類不實現可序列化接口,使用二級緩存,那麼會報下列異常:
緩存
org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException:
默認配置:
session
<settings> <setting name="cacheEnabled" value="true"/> </settings>
必須開啓緩存配置,才能使用mybatis的二級緩存,否則不能使用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
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"/> //只讀