0
点赞
收藏
分享

微信扫一扫

MyBatis-05

西红柿上校 2022-02-18 阅读 87

MyBatis-05

一、缓存简介

缓存(Cache),指的是将原本从数据库中读出来的数据放入内存中保存起来,下一次访问同样的数据时,直接从内存中进行读取,不再去查询数据库。因为大多数情况下,客户端执行的大多是查询的操作,因此,我们可以在客户端与服务器之间或者服务器与数据库之间加上一层数据缓存层,用来提高查询效率

优点:

  • 减少了对数据库的读操作,数据库的压力降低
  • 加快了响应速度

缺点:

  • 因为内存断电就清空数据,存放到内存中的数据可能丢失
  • 缓存中的数据可能与数据库中数据不一致
  • 内存的成本高
  • 内存容量相对硬盘小

二、一级缓存

在MyBatis中一级缓存也被叫做本地缓存

  • 与数据库同一会话期间将查询到的数据放在本地缓存
  • 在以后如果需要同样的数据,就会直接去本地缓存中拿,如果没有则会再次去查询数据库
  • 一级缓存的作用域为SqlSession创建到SqlSession关闭

一级缓存实现:

Mapper接口:

public interface UserMapper {

    User getUser(@Param("uid") long id);

}

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">
<!--namespace:对应数据访问层的接口-->
<mapper namespace="com.jack.dao.UserMapper">
    <select id="getUser" parameterType="long" resultType="user">
        select * from test.user where id = #{uid}
    </select>
</mapper>

单元测试:

@Test
public void testCache1(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    System.out.println(mapper.getUser(1));
    System.out.println("=======================");

    System.out.println(mapper.getUser(1));
    sqlSession.close();
}

输出:

在这里插入图片描述

结论:

从输出中可以看出只从数据库中读取了一次,第二次读取相同数据时直接从缓存中取得

三、二级缓存

在MyBatis中一级缓存也被叫做全局缓存

  • 基于namespace命名空间级别的缓存,一个命名空间(一个Mapper文件)对应一个二级缓存
  • 作用域比一级缓存广,即使一个会话关闭,启动另一个会话后再查询相同的数据仍然会从缓存中读取
  • 工作机制:
    • 一个会话查询一条数据,该数据被保存在当前会话的一级缓存中
    • 当前会话结束后,一级缓存将不复存在,数据将从一级缓存迁移到mapper文件对应的二级缓存中
    • 一个新的对话开启,读取相同的数据时,会从对应mapper文件的二级缓存中读取

二级缓存实现:

首先在config文件中配置settings允许全局缓存:

<setting name="cacheEnabled" value="true"/>

在对应的Mapper文件中添加全局缓存开启标签:

<cache/>

单元测试:

@Test
public void testCache2(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    System.out.println(mapper.getUser(1));
    sqlSession.close();

    System.out.println("=======================");

    SqlSession sqlSession1 = MyBatisUtils.getSqlSession();
    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);

    System.out.println(mapper1.getUser(1));
    sqlSession1.close();
}

输出:

在这里插入图片描述

结论:

从上面的输出可以看出二级缓存作用域更强更广

四、MyBatis缓存原理

一张图即可说明:

在这里插入图片描述

解释:

  • 用户查询先从二级缓存中查找,若有,则直接返回,若无,去一级缓存查
  • 一级缓存中若有,则直接返回,若无,去数据库中查询
  • 查询完毕后将保存至一级缓存,若此时会话关闭,则将缓存提交至对应Mapper的二级缓存中

至此,MyBatis主要部分学习完毕,有任何问题可以在评论区提出或私信博主,一起讨论,一起进步!

相关文章:

  • MyBatis-02

  • MyBatis-03

  • MyBatis-04

  • 举报

    相关推荐

    0 条评论