Mybatis掌握第三章—进阶

目录
多对一的处理
一对多的处理
动态sql
一级缓存与二级缓存
Mybatis缓存原理
自定义缓存
总结

一级缓存与二级缓存

简介:

1、什么是缓存 [ Cache ]?
存在内存中的临时数据。
将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
2、为什么使用缓存?
减少和数据库的交互次数,减少系统开销,提高系统效率。
3、什么样的数据能使用缓存?
经常查询并且不经常改变的数据。
Mybatis缓存:
MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存

  • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
  • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存(接口级别)。为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
一级缓存

一级缓存也叫本地缓存:

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
  • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库
    测试步骤:
    1,开启日志!
    2,测试在一个Session查询两侧相同记录
    3,查看日志输出
    代码
  @Test
        public void getUserID(){
            SqlSession session = MybatisUtils.getSession();
            UserMapper mapper = session.getMapper(UserMapper.class);
            User userID = mapper.getUserID(2);
            System.out.println(userID);
            System.out.println("-------------------------------");
            User userID2 = mapper.getUserID(2);
            System.out.println(userID2);
            session.close();
        }

两次查询语句一样,只有一个查询语句,说明缓存正常
在这里插入图片描述
缓存失效情况
1.查询不同语句的情况

            User userID = mapper.getUserID(2);
            System.out.println(userID);
            System.out.println("-------------------------------");
            User userID2 = mapper.getUserID(3);

在这里插入图片描述
2,增删改操作,可能会改变原来数据,所以必定会刷新缓存
增加一个修改操作,在中间

  User userID = mapper.getUserID(2);
            System.out.println(userID);
            mapper.updateUser(new User(5,"aaa","31535131"));
            System.out.println("-------------------------------");
            User userID2 = mapper.getUserID(2);

查询了三次
在这里插入图片描述
3,查询不同的Mapper
4,手动清除

 User userID = mapper.getUserID(2);
            System.out.println(userID);
            //mapper.updateUser(new User(5,"aaa","31535131"));
            session.clearCache();//手动清理缓存
            System.out.println("-------------------------------");
            User userID2 = mapper.getUserID(2);

在这里插入图片描述
小结:一级缓存是默认开启的,只在一次SqlSession中有效,就是拿到连接到关闭这个区间段
一级缓存就是一个map

二级缓存

工作机制

  • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
  • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
  • 新的会话查询信息,就可以从二级缓存中获取内容;
  • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

使用步骤:
1、开启全局缓存 【mybatis-config.xml】

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

2、去每个mapper.xml中配置使用二级缓存,这个配置非常简单;【xxxMapper.xml】

<cache/>
<select id="selectUser" resultType="pojo.User" useCache="true"><!--也可以在这里使用-->
  
  </select>

官方示例=====>查看官方文档
<cache
 eviction="FIFO"
 flushInterval="60000"
 size="512"
 readOnly="true"/>
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

测试:

 @Test
        public void getUserID(){
            SqlSession session = MybatisUtils.getSession();
            SqlSession session2 = MybatisUtils.getSession();
            UserMapper mapper = session.getMapper(UserMapper.class);
            UserMapper mapper2 = session2.getMapper(UserMapper.class);
            User userID = mapper.getUserID(2);
            System.out.println(userID);
            session.close();
            System.out.println("-------------------------------");
            User userID2 = mapper2.getUserID(2);
            System.out.println(userID2);
            System.out.println(userID==userID2);

            session2.close();
        }

两个Session分开关闭,第一个关闭后,一级缓存死亡,交给二级缓存,然后进行第二次查询,直接从二级缓存中拿到。所以只查询了一次
在这里插入图片描述
问题:
1,cache没有写策略的时候,我们需要将实体类序列化

Caused by: java.io.NotSerializableException: pojo.User

在这里插入图片描述
小结:只要开启了二级缓存,在同一个Mapper下有效
所有的数据都会先存在一级缓存中,然后提交到二级

Mybatis缓存原理

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值