美文网首页程序员Java学习笔记
八、Mybatis一级缓存和二级缓存

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

作者: 数独题 | 来源:发表于2016-11-28 20:33 被阅读105次
    • 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 **Session****flush **或 **close **之后,该 Session 中的所有 Cache 就将清空。

    • 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache, HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。

    • 对于缓存数据更新机制,当某一个作用域(一级缓存 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

    <?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">
    <mapper namespace="com.config.CUserMapper">
     
        <select id="getUser" parameterType="int" resultType="com.entity.CUser">
            select * from c_user where id=#{id}
        </select>
        <update id="updateUser" parameterType="com.entity.CUser">
            update c_user set
            name=#{name}, age=#{age} where id=#{id}
        </update>
    </mapper>
    

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

    config.xml

    <mappers>
          <mapper resource="com/config/CUserMapper.xml"/>
    </mappers>
    

    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二级缓存

    • 映射文件中增加<cache></cache>

    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 个对象
    <cache
         eviction="FIFO" //回收策略为先进先出
         flushInterval="60000" //自动刷新时间 60s
         size="512" //最多缓存 512 个引用对象
         readOnly="true"/> //只读
    

    相关文章

      网友评论

        本文标题:八、Mybatis一级缓存和二级缓存

        本文链接:https://www.haomeiwen.com/subject/fznopttx.html