八、Mybatis一级缓存和二级缓存

八、Mybatis一级缓存和二级缓存
文章图片

  • 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 **Session****flush **或 **close **之后,该 Session 中的所有 Cache 就将清空。
  • 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache, HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。
  • 【八、Mybatis一级缓存和二级缓存】对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
8.1一级缓存 8.1.1准备数据库表和数据
CREATE TABLE c_user( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20), age INT ); INSERT INTO c_user(NAME, age) VALUES('Tom', 12); INSERT INTO c_user(NAME, age) VALUES('Jack', 11);

8.1.2创建实体类
CUser.java
package com.entity; import java.io.Serializable; public class CUser implements Serializable { private int id; private String name; private int age; public CUser() { super(); } public CUser(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "CUser [id=" + id + ", name=" + name + ", age=" + age + "]"; }}

8.1.3创建映射文件
CUserMapper.xml
select * from c_user where id=#{id} update c_user set name=#{name}, age=#{age} where id=#{id}

8.1.4在config.xml中注册映射文件
config.xml

8.1.5创建测试类
Test8.java
package com.test; import java.io.IOException; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import com.entity.CUser; import com.util.MybatisUtil; /* * 测试缓存 * 1.一级缓存:是session级的缓存 *a.执行session.clearCache(); *b.执行CUD操作 *c.session.close(),再打开另外一个session,两者不是同一个session. * 2.二级缓存:是sessionFactory级的缓存 * */ public class Test8 {//一级缓存测试 @Test public void testCacheOne() throws IOException {SqlSession session=MybatisUtil.getSession(); String statement="com.config.CUserMapper.getUser"; CUser user=session.selectOne(statement, 1); System.out.println(user); //测试缓存,不发生第二条select语句 user=session.selectOne(statement, 1); System.out.println(user); System.out.println(session.hashCode()); System.out.println("----------------------"); //a.执行session.clearCache(); //session.clearCache(); //b.执行CUD操作 //session.update("com.config.CUserMapper.updateUser", new CUser(1,"Tom",13)); //session.commit(); user=session.selectOne(statement, 1); System.out.println(session.hashCode()); System.out.println(user); session.close(); } }

8.2二级缓存
  • 映射文件中增加
8.2.1测试类
Test8.java
package com.test; import java.io.IOException; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import com.entity.CUser; import com.util.MybatisUtil; /* * 测试缓存 * 1.一级缓存:是session级的缓存 *a.执行session.clearCache(); *b.执行CUD操作 *c.session.close(),再打开另外一个session,两者不是同一个session. * 2.二级缓存:是sessionFactory级的缓存 * */ public class Test8 {//二级缓存测试 @Test public void testCacheTwo() throws IOException {SqlSession session1=MybatisUtil.getSession(); SqlSession session2=MybatisUtil.getSession(); String statement="com.config.CUserMapper.getUser"; CUser user=session1.selectOne(statement, 1); session1.close(); System.out.println(user); user=session2.selectOne(statement, 1); System.out.println(user); session1.close(); session2.close(); } }

8.3补充说明
  • 映射语句文件中的所有 select 语句将会被缓存。
  • 映射语句文件中的所有 insert, update 和 delete 语句会刷新缓存。
  • 缓存会使用 Least Recently Used( LRU,最近最少使用的)算法来收回。
  • 缓存会根据指定的时间间隔来刷新。
  • 缓存会存储 1024 个对象
//只读

    推荐阅读