当前位置: 首页 > news >正文

MyBatis的缓存

MyBatis的缓存

创建工程:
在这里插入图片描述

1缓存介绍

  • 为什么使用缓存?

    首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少IO、硬盘读写次数、提高效率

  • Mybatis中的一级缓存和二级缓存?

    • 一级缓存:

      它指的是mybatis中的SqlSession对象的缓存。当我们执行完查询之后,查询的结果会同时存在在SqlSession为我们提供的一块区域中。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。当SqlSession对象消失时,Mybatis的一级缓存也就消失了。

    • 二级缓存:

      它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessioFactory对象创建的SqlSession共享其缓存。

2.一级缓存

2.1.mapper

public interface UserDao {//根据id查询用户信息public User findUserById(Integer id);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.dao.UserDao"><select id="findUserById" resultType="User" parameterType="int">select * from user where id=#{id}</select>
</mapper>

2.2.测试一级缓存

    @Testpublic void testFindUserById() throws Exception{SqlSession sqlSession1 = sqlSessionFactory.openSession();UserDao userDao = sqlSession1.getMapper(UserDao.class);User user1 = userDao.findUserById(41);//执行查询System.out.println("第一次查询:" + user1);User user2 = userDao.findUserById(41);//不执行查询System.out.println("第二次查询:" + user2);SqlSession sqlSession2 = sqlSessionFactory.openSession();userDao = sqlSession2.getMapper(UserDao.class);User user3 = userDao.findUserById(41);//执行查询System.out.println("第三次查询:" + user1);}

2.3.一级缓存的分析

一级缓存是SqlSession范围的缓存,当调用SqlSession的commit(),close()等方法时,就会清空一级缓存。

在这里插入图片描述

  1. 第一次发起查询用户id为 1 的用户信息,先去找缓存中是否有id为 1 的用户信息,如果没有,从数据库查询用户信息。 得到用户信息,将用户信息存储到一级缓存中。

  2. 如果sqlSession去执行 commit操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读

  3. 第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

2.4.测试清空一级缓存

    @Testpublic void testFindUserById() throws Exception{UserDao userDao = sqlSession.getMapper(UserDao.class);User user1 = userDao.findUserById(41);//执行查询System.out.println("第一次查询:" + user1);User user2 = userDao.findUserById(41);//不执行查询System.out.println("第二次查询:" + user2);sqlSession.commit();User user3 = userDao.findUserById(41);//执行查询System.out.println("第三次查询:" + user1);}

3.二级缓存

3.1.pojo

注意:当我们在使用二级缓存时,所缓存的类一定要实现java.io.Serializable接口,这种就可以使用序列化方式来保存对象。

public class User implements Serializable {private Integer id;private String username;private String password;private Date birthday;private String sex;private String address;//set get... ...
}    

3.2.开启二级缓存

  1. 在SqlMapConfig.xml 文件开启二级缓存

    <settings><!-- 开启二级缓存的支持 --><setting name="cacheEnabled" value="true"/>
    </settings>
    
  2. 配置相关的Mapper映射文件

    <mapper namespace="com.by.dao.UserDao"><!-- 开启二级缓存的支持 --><cache></cache>
    

3.3.测试二级缓存

    @Testpublic void testSecondUserById(){SqlSession sqlSession1 = sqlSessionFactory.openSession();UserDao userDao = sqlSession1.getMapper(UserDao.class);User user1 = userDao.findUserById(41);//执行查询System.out.println("第一次查询:" + user1);sqlSession1.commit();//二级缓存在sqlSession.commit()或者sqlSession.close()之后生效SqlSession sqlSession2 = sqlSessionFactory.openSession();UserDao userDao2 = sqlSession2.getMapper(UserDao.class);User user2 = userDao2.findUserById(41);//不执行查询System.out.println("第二次查询:" + user2);}

3.4.二级缓存分析

二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

二级缓存结构图:

3.5.测试清空二级缓存

    @Testpublic void testSecondUserById(){SqlSession sqlSession1 = sqlSessionFactory.openSession();UserDao userDao = sqlSession1.getMapper(UserDao.class);User user1 = userDao.findUserById(43);//执行查询System.out.println("第一次查询:" + user1);sqlSession1.commit();SqlSession sqlSession3 = sqlSessionFactory.openSession();UserDao userDao3 = sqlSession3.getMapper(UserDao.class);userDao3.deleteUserById(41);sqlSession3.commit();SqlSession sqlSession2 = sqlSessionFactory.openSession();UserDao userDao2 = sqlSession2.getMapper(UserDao.class);User user2 = userDao2.findUserById(43);不执行查询System.out.println("第二次查询:" + user2);sqlSession2.commit();sqlSession2.close();}

相关文章:

  • Python pandas 操作 excel 详解
  • electron autoUpdater自动更新使用示例 客户端+服务端
  • Debian Linux完全卸载gitlab-ce
  • Servlet见解2
  • Typora Mac激活
  • 2024 年甘肃省职业院校技能大赛 应用软件系统开发赛项样题
  • Elasticsearch可视化平台Kibana [ES系列] - 第498篇
  • html页面 通过jquery.i18n.properties添加多语言
  • web网页端使用webSocket实现语音通话功能(SpringBoot+VUE)
  • CMMI-项目总体计划模版
  • 【Jmeter、postman、python 三大主流技术如何操作数据库?】
  • 前端---css 选择器
  • iPad绘画之旅:从小白到文创手账设计的萌系简笔画探索
  • 基于双闭环PI的SMO无速度控制系统simulink建模与仿真
  • 华为gre隧道全部跑静态路由
  • [deviceone开发]-do_Webview的基本示例
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • C++类中的特殊成员函数
  • canvas 五子棋游戏
  • ES10 特性的完整指南
  • FastReport在线报表设计器工作原理
  • Flex布局到底解决了什么问题
  • JS基础之数据类型、对象、原型、原型链、继承
  • mysql innodb 索引使用指南
  • MySQL主从复制读写分离及奇怪的问题
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • SpiderData 2019年2月16日 DApp数据排行榜
  • Windows Containers 大冒险: 容器网络
  • 阿里云应用高可用服务公测发布
  • 动态规划入门(以爬楼梯为例)
  • 和 || 运算
  • 如何进阶一名有竞争力的程序员?
  • 项目实战-Api的解决方案
  • 一份游戏开发学习路线
  • 赢得Docker挑战最佳实践
  • 自制字幕遮挡器
  • Java数据解析之JSON
  • # 数论-逆元
  • #define 用法
  • (06)Hive——正则表达式
  • (6)STL算法之转换
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (六)软件测试分工
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)平衡树
  • (转)四层和七层负载均衡的区别
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .Net CF下精确的计时器
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NET单元测试
  • [04] Android逐帧动画(一)