mybatis13---2级缓存

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis13---2级缓存相关的知识,希望对你有一定的参考价值。

验证内置的2级缓存

Ehcache缓存的配置

01.引入需要的ehcache 和mybatis-ehcache 两个jar包

02.在mapper文件中增加  <cache type="org.mybatis.caches.ehcache.EhcacheCache"/> <!-- 配置Ehcache缓存 -->

org.mybatis.caches.ehcache.EhcacheCache就是在mybatis-ehcache这个jar包中

03.引入需要的ecache.xml文件   就在ecache.jar中

 

创建对应的dao

public interface StudentDao {
    /**
     *  验证mybatis2级缓存!
     */
    Student selectStudentById(Integer sId);
}

创建对应的mapper文件

<?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="cn.bdqn.dao.StudentDao">
  <cache/> <!-- 配置2级缓存 -->
     <select id="selectStudentById" resultType="Student">
      select  sid,sname from  student where sid=#{xxx}
    </select>
    
</mapper>

实体类实现Serializable序列化接口

/**
 *学生对应的实体类
 */
public class Student  implements Serializable {
    
    private  Integer sId;
    private  String sName;

    public Integer getsId() {
        return sId;
    }
    public void setsId(Integer sId) {
        this.sId = sId;
    }
    public String getsName() {
        return sName;
    }
    public void setsName(String sName) {
        this.sName = sName;
    }
    public Student(Integer sId, String sName) {
        super();
        this.sId = sId;
        this.sName = sName;
    }
    public Student() {
        super();
    }
    @Override
    public String toString() {
        return "Student [sId=" + sId + ", sName=" + sName +"]";
    } 
}

把log4j的配置文件中的显示改成

增加测试类代码

package cn.bdqn.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import cn.bdqn.bean.Student;
import cn.bdqn.dao.StudentDao;
import cn.bdqn.util.SessionUtil;

public class TeacherTest {
    StudentDao dao;
    SqlSession session;

    @Before
    public void before() {
        // 因为需要关闭session 需要把session提取出去
        session = SessionUtil.getSession();
        dao = session.getMapper(StudentDao.class);
    }

    @After
    public void after() {
        if (session != null) {
            session.close();
        }
    }

/**
 * 验证2级缓存
 * 
 * 开启内置2级缓存的步骤
 * 01.实体类对象 要实现serializable 序列化接口
 * 02.在mapper文件中 增加  <cache/>节点
 */
    @Test
    public void test1() {
        Student student = dao.selectStudentById(1);
        System.out.println(student);
        
        session.close(); //关闭了session   一级缓存中的数据肯定清空了
        
        session = SessionUtil.getSession();  //再次获取session 查询数据
        dao = session.getMapper(StudentDao.class);
        //这时候不会再有sql语句了  因为2级缓存中存在相同的查询(mapper文件中sql的id)和相同的sql语句
        Student student2 = dao.selectStudentById(1);
        System.out.println(student2);
    }
    
}

运行的结果:

验证增删改对2级缓存的影响

在dao中新增方法

public interface StudentDao {
    /**
     *  验证mybatis2级缓存!
     */
    Student selectStudentById(Integer sId);
    
    /**
     * 验证增删改查对2级缓存的影响!
     */
    void addStudent(Student student);
}

在mapper文件中新增

<?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="cn.bdqn.dao.StudentDao">
  <cache/> <!-- 配置2级缓存 -->
     <select id="selectStudentById" resultType="Student">
      select  sid,sname from  student where sid=#{xxx}
    </select>
    
   <!-- 新增一个学生   验证对2级缓存的影响  标签中 增加 flushCache="false" 可以设置在新增数据的时候不刷新2级缓存
  但是一级缓存不能配置 也就是 只要是一级缓存的增删改 都会刷新 -->
  <insert id="addStudent">
    
insert into student values(#{sId},#{sName}) <!--#{sId},#{sName} 对应的是实体类中的属性 -->
  
</insert>
</
mapper>

在测试类中新增

   /**
     * 验证增删改对2级缓存的影响
     */
    @Test
    public void test2() {
        Student student = dao.selectStudentById(1);
        System.out.println(student);
        
        session.close(); //关闭了session   一级缓存中的数据肯定清空了
        
        session = SessionUtil.getSession();  //再次获取session 查询数据
        dao = session.getMapper(StudentDao.class);
        //新增学生信息  看看对2级缓存的影响
        dao.addStudent(new Student(66,"测试"));
        
        Student student2 = dao.selectStudentById(1);
        System.out.println(student2);
    }

得到的结果:

2级缓存的关闭

   /**
     *  2级缓存的关闭
     *  01.局部关闭
     * 在mapper文件中修改
     * <select id="selectStudentById"  useCache="false" resultType="Student">
     * 增加了useCache="false"  相当于 局部关闭 2级缓存  useCache默认值为true===》把查询放入2级缓存
     * 02.全局关闭
     *   在mybatis.xml文件中增加
     *   <settings>
     *         <!--全局关闭2级缓存  -->
     *          <setting name="cacheEnabled" value="false"/>
     *   </settings>
     */
    
    @Test
    public void test3() {
        Student student = dao.selectStudentById(1);
        System.out.println(student);
        
        session.close(); //关闭了session   一级缓存中的数据肯定清空了
        
        session = SessionUtil.getSession();  //再次获取session 查询数据
        dao = session.getMapper(StudentDao.class);
        //这时候不会再有sql语句了  因为2级缓存中存在相同的查询(mapper文件中sql的id)和相同的sql语句
        Student student2 = dao.selectStudentById(1);
        System.out.println(student2);
    }
    
    /**
     * 2级缓存的使用原则:
     * 01. 很少被修改的数据 
     * 02. 不是很重要的数据,允许出现偶尔并发的数据 
     * 03. 不会被并发访问的数据 
     * 04.多个namespace不能操作同一张表
     * 05.不能在关联关系表上执行增删改操作
     */

 

以上是关于mybatis13---2级缓存的主要内容,如果未能解决你的问题,请参考以下文章

mybatis13---2级缓存

MyBatis从入门到精通—源码剖析之二级缓存细节

Mybatis的两级缓存初解

五mybatis两级缓存

mybatis缓存之一级缓存

Mybatis的两级缓存初解