Mybatis缓存机制

一.什么是缓存?

    缓存即为存在内存中的临时数据.将用户经常查询的数据存放在缓存(内存)中,用户去查询数据就不用去每次去数据库中查询,而是去缓存中查询,从而提高了查询的效率,解决了高并发系统的性能问题.

  • 使用缓存的方式可以减少和数据库的交互次数,减少系统开销,提高系统效率

  • 将经常查询的并且不经常改变的数据适合使用缓存;反之,不经常查询且经常改变的数据不适合使用缓存

二.Mybatis缓存分类

Mybatis中将缓存分为一级缓存和二级缓存

1.一级缓存

    一级缓存是Mybatis默认开启的缓存,我们不用自己去手动开启.它是SQLSession级别的缓存,也称为本地缓存,当调用SqlSession的修改,添加,删除,commit().close(),clearCache()等方法时就会清空一次一级缓存.

    一次查询的结果我们将它暂时存放在缓存中,我们下次再去查询的时候就可以去缓存中查找,而不用去与数据库交互查询.

栗子:

此处我们以查询学生列表为例
1.接口中的方法:

List<Student> findStudentlist(Student student);

2.mapper.xml:

<mapper namespace="com.ffyc.mybatisdemo.dao.StudentDao">
     
     <sql id="selectStudent">
         SELECT s.id,s.name,s.gender,g.name gname
             FROM student s
             LEFT JOIN grade g
             ON s.gradeid = g.id
             LEFT JOIN admin a
             ON s.adminid = a.id
     </sql>
     
     <select id="findStudentlist" resultType="com.ffyc.mybatisdemo.model.Student">
        <include refid="selectStudent"></include>
     </select>
 </mapper>

3.测试类:

 package com.ffyc.mybatisdemo.test;
 ​
 import com.ffyc.mybatisdemo.dao.StudentDao;
 import com.ffyc.mybatisdemo.model.Student;
 import com.ffyc.mybatisdemo.util.MybatisUtil;
 import org.apache.ibatis.session.SqlSession;
 import org.junit.Test;
 ​
 import java.util.ArrayList;
 import java.util.List;
 ​
 /*
     多表查询  多对1
  */
 public class TestStudent {
 ​
     @Test
     //一级缓存
     public void cacheDemo() {
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
         Student student = new Student();
         List<Student> students = studentDao.findStudentlist(student);
         System.out.println(students);
 ​
         System.out.println("-----------------------------");
         
         List<Student> students2 = studentDao.findStudentlist(student);
         System.out.println(students2);
         sqlSession.close(); //关闭SQLSession,会清空一级缓存
     }
 }
 ​

4.查询结果:

     由查询结果我们可以看到,我们执行了两次相同的查询方法,但是从日志中可以看到,只执行了一次查询语句.这就体现出了一级缓存的作用,我们不用频繁与数据库进行交互.

2.二级缓存

    二级缓存是SQLSessionFactory级别的缓存,作用域为一个namespace,也就是在同一个mapper下都会生效,由多SqlSession所共享.需要我们手动开启和配置.

注:

二级缓存只有在一级缓存死掉的时候才会生效.

二级缓存的配置:

1.开启全局二级缓存:

<!--全局配置-->
     <settings>
         <!--开启全局二级缓存-->
         <setting name="cacheEnabled" value="true"></setting>
     </settings>

2.将所有实体类实现实例化接口: java.io.Serializable

 public class Admin implements Serializable{
     
 }

3.配置映射文件:
    mapper映射在配置文件中添加<cache/>表示此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="com.ffyc.mybatisdemo.dao.StudentDao">
     <!--表示此mapper开启二级缓存-->
     <cache><cache/>
 </mapper>

栗子:

这里我们还是以之前的查询学生列表为例:

1.接口中的方法:

 List<Student> findStudentlist(Student student);

2.mapper.xml:

 <mapper namespace="com.ffyc.mybatisdemo.dao.StudentDao">
     
     <sql id="selectStudent">
         SELECT s.id,s.name,s.gender,g.name gname
             FROM student s
             LEFT JOIN grade g
             ON s.gradeid = g.id
             LEFT JOIN admin a
             ON s.adminid = a.id
     </sql>
     
     <select id="findStudentlist" resultType="com.ffyc.mybatisdemo.model.Student">
        <include refid="selectStudent"></include>
     </select>
 </mapper>

3.测试类:

 package com.ffyc.mybatisdemo.test;
 ​
 import com.ffyc.mybatisdemo.dao.StudentDao;
 import com.ffyc.mybatisdemo.model.Student;
 import com.ffyc.mybatisdemo.util.MybatisUtil;
 import org.apache.ibatis.session.SqlSession;
 import org.junit.Test;
 ​
 import java.util.ArrayList;
 import java.util.List;
 ​
 ​
 public class TestStudent {
     @Test
     //二级缓存
     public void cacheDemo2() {
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
         Student student = new Student();
         List<Student> students = studentDao.findStudentlist(student);
         System.out.println(students);
 ​
         SqlSession sqlSession2 = MybatisUtil.getSqlSession();
         StudentDao studentDao2 = sqlSession2.getMapper(StudentDao.class);
         List<Student> students2 = studentDao2.findStudentlist(student);
         System.out.println(students2);
         sqlSession.close();
     }
 }
 ​

4.运行结果:

修改:

 package com.ffyc.mybatisdemo.test;
 ​
 import com.ffyc.mybatisdemo.dao.StudentDao;
 import com.ffyc.mybatisdemo.model.Student;
 import com.ffyc.mybatisdemo.util.MybatisUtil;
 import org.apache.ibatis.session.SqlSession;
 import org.junit.Test;
 ​
 import java.util.ArrayList;
 import java.util.List;
 ​
 public class TestStudent {
     @Test
     //二级缓存
     public void cacheDemo2() {
         SqlSession sqlSession1 = MybatisUtil.getSqlSession();
         StudentDao studentDao = sqlSession1.getMapper(StudentDao.class);
         SqlSession sqlSession2 = MybatisUtil.getSqlSession();
         StudentDao studentDao2 = sqlSession2.getMapper(StudentDao.class);
         Student student = new Student();
         List<Student> students = studentDao.findStudentlist(student);
         System.out.println(students);
         sqlSession1.close();  //关闭SQLSession,会清空一级缓存,并将一级缓存中的数据放入二级缓存中
 ​
         List<Student> students2 = studentDao2.findStudentlist(student);
         System.out.println(students2);
         sqlSession2.close();
     }
 }
 ​

运行结果:

总结:

  • Mybatis的一级缓存时SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交,关闭,以及其他的更新数据库的操作发生时,以及缓存就会被清空.

  • 二级缓存是SQLSessionFactory级别的缓存,同一个SQLSessionFactory产生的SqlSession都共享一个二级缓存,二级缓存中存储的是数据,当命中二级缓存时,通过存储的数据构成对象返回.

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会写代码的菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值