缓存在哪里_什么是MyBatis缓存技术
MyBatis缓存
引言
在一个Web项目中,查询数据库中的操作算是一个非常常用的操作,但是有些数据会被经常性的查询,而每一次都去数据库中查询这些重复的数据,会很消耗数据库的资源,同时使得查询效率也很低,而 MyBatis 中就通过缓存技术来解决这样的问题,也就是说:将一些经常查询,并且不经常改变的,以及数据的正确对最后的结果影响不大的数据,放置在一个缓存容器中,当用户再次查询这些数据的时候,就不必再去数据库中查询,直接在缓存中提取就可以了
注:缓存可以简单理解为存在于内存中的临时数据
MyBatis 提供了 一级缓存和二级缓存两种形式
- 一级缓存 :它是 SqlSession 级别的缓存,SqlSession 类的实例对象中提供了一个 HashMap 的结构,可以用于存储缓存数据,当我们再次查询同一数据的时候,MyBatis 会先去 SqlSession 中查询,有的话,就直接调用
- 二级缓存 :是Mapper 级别的缓存,也就是说,如果多个 SqlSession 类的实例,去操作同一个Mapper配置文件中的SQL,这些实例对象可以共用二级缓存
一级缓存
(1) 基本阐述
上面我们总的讲了一级缓存的原理,现在梳理一下它细节
以一个通过 id 查询用户的例子来说
- 第一次查询 id 为某个值的用户信息时,先去 SqlSesion 的一级缓存中去寻找,如果找到了,就直接用,如果没有找到就去数据库中去查,然后将查到的内容存到一级缓存区域
- 但是,如果在下一次操作中,执行了 commit 操作,也就是执行了增删改的操作,一级缓存区域内的内容会被清空,这是为了保证缓存中的数据的有效性,避免脏读的产生
(2) 程序演示
演示前,我把需要准备的一些类或者表现贴出来
User表
CREATE TABLE USER ( `id` INT(11)NOT NULL AUTO_INCREMENT, `username` VARCHAR(32) NOT NULL COMMENT '用户名', `telephone` VARCHAR(11) NOT NULL COMMENT '手机', `birthday` DATETIME DEFAULT NULL COMMENT '生日', `gender` CHAR(1) DEFAULT NULL COMMENT '性别', `address` VARCHAR(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`)) ENGINE=INNODB DEFAULT CHARSET=utf8;
User实体类
public class User implements Serializable { private Integer id; private String username; private String telephone; private Date birthday; private String gender; private String address; ...... 请补充 get set 方法}
UserMapper接口
public interface UserMapper { /** * 根据id查询用户信息 * @param userId * @return */ User findById(Integer userId);}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?> SELECT * FROM user where id = #{uid}
测试方法
/*** 测试查询所有*/@Testpublic void testFirstLevelCache() { User user1 = userMapper.findById(16); System.out.println(user1); User user2 = userMapper.findById(16); System.out.println(user2); System.out.println(user1 == user2);}
执行效果
可以很明显的看到,当我们在同一个 sqlSession的情况下,当我们第一次查询 id 值为 16 的用户时,从数据库中确实查询到了数据,而第二次查询的时候,却没有任何日志的数据,而同时我们可以看到,通过输出语句,看到两个对象是完全相同的,这也就意味着,第二次查询不是从数据库查询出来的,而是从缓存中
二级缓存
(1) 基本阐述
通过上面的简单认识,我们认识到一级缓存是基于同一个 SqlSession的,但是有时候由于方法封装的原因,或者在查询完,SqlSession 对象会关闭,一级缓存就清空了,会导致无法从中获取内容
二级缓存的可以帮我们解决一级缓存无法使用的情况,前面已经说过二级缓存是Mapper 级别的缓存,多个SqlSession类的实例对象加载同一个Mapper配置文件,并执行其中SQL配置的收,他们就共享同一个 Mapper 缓存,执行流程也与一级缓存基本是一致的
- 查询时,先去Mapper缓存区去找这个值,如果找不到,就去数据库查,然后将查询到的结果存储到缓存中,等下次使用
- 当某个 SqlSession 类的实例对象执行了增删改操作时,二级缓存会被清空
还依据刚开始准备的代码,我们直接写出其测试代码,看看在不同的 SqlSession 下,加载同一个Mapper的SQL是否会看到二级缓存的效果
(2) 程序演示
测试代码
@Testpublic void testSecondLevelCache() { SqlSession sqlSession1 = factory.openSession(); UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); User user1 = mapper1.findById(16); sqlSession1.close(); SqlSession sqlSession2 = factory.openSession(); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); User user2 = mapper2.findById(16); sqlSession1.close(); System.out.println(user1 == user2);}
第一次执行效果
看完测试代码,我们发现,SQL执行了两次,很显然,没有达到了我们的期望,那么是哪里不对呢?
答案是,在MyBatis中一级缓存是默认开启的,而二级缓存则需要进行配置开启
要开启二级缓存,需要进行两个操作步骤
- ①:在总配置文件 SqlMapConfig.xml 中配置 setting属性
- ②:在SQL映射文件中开启二级缓存
通过官网的文档,可以看到,默认值就是true,所以,不配置也是可以的,不过我们还是先给出来
修改 SqlMapConfig.xml
修改 UserMapper.xml
只需要在文件中添加一个 cache标签就可以了,非常简单
执行效果
还有一个需要注意的地方,那就是我们最后做的判断 System.out.println(user1 == user2); 为什么的到的结果却是 false呢?
这是因为,在二级缓存中,存入的是值,而不是对象,当需要使用的时候,会创建出新的用户,然后将值传入,所以这里是不等的
不过使用二级缓存的时候,一定要谨慎,因为有时候不同的namespace下的 SQL配置中可能缓存着相同的数据,如我们上面的例子,UserMapper.xml 中有关于 user表的操作,但是如果在其他 Mmpper.xml 中仍然有针对 user 单表的操作,这会导致两方数据不一样,如果在我们 UserMapper.xml 进行了刷新缓存,但是另一个Mapper.xml 中可能仍有效,所以可能会出现错误
缓存在哪里_什么是MyBatis缓存技术相关推荐
- DOTA2怎么清除缓存_5分钟带你走进mybatis缓存
前言 为什么要缓存 MyBatis缓存 一级缓存 二级缓存 二级缓存应该开启吗 自定义缓存 总结 前言 在计算机的世界中,缓存无处不在,操作系统有操作系统的缓存,数据库也会有数据库的缓存,各种中间件如 ...
- session.merge 缓存不更新_这几个缓存更新的设计你都知道吗?
前言 Hello,everybody,我是asong,上一篇文章我们一起聊一聊了面试中几个常见的缓存问题,今天我依然聊一聊缓存,不过今天我们聊的不是面试了,我们一起来看一看我们在系统中缓存更新的设计, ...
- spring默认缓存管理器_使用Spring的缓存管理器缓存Web内容
spring默认缓存管理器 在这篇文章中,我想向大家展示如何使用Spring的CacheManager,@ Cacheable和JMX批注来缓存和管理Web内容的缓存的基础知识. 想象一下一个网上商店 ...
- iframe缓存无法清空_详解Http缓存机制
前言 Web的缓存可以粗略分为两种:服务器缓存和浏览器缓存.服务器缓存(如代理服务器缓存.CDN等)让资源加载得更快,可有效提高第一次访问的加载速度:而浏览器缓存可以跳过请求重复的资源,大幅度提高第二 ...
- android手机 手动 清理缓存,安卓手机缓存怎么清理_安卓手机清理缓存的具体步骤-系统城...
安卓手机使用时间久了之后,一些软件会产生较多的缓存,从而导致手机运行速度变慢,所以我们就需要来清理这些缓存,但有的网友不太清楚安卓手机缓存怎么清理,所以今天小编为大家整理分享的就是关于安卓手机清理缓存 ...
- js app缓存自动刷新_如何通过清除缓存来刷新App Store中的内容
js app缓存自动刷新 Are you finding that you're not seeing new apps on the App Store, or that updates to ap ...
- 【Java从0到架构师】MyBatis - 缓存_构造方法
缓存_构造方法 缓存 一级缓存 - SqlSession 二级缓存 开启二级缓存 useCache - 是否开启二级缓存 flushCache - 是否需要清楚缓存 指定构造方法 XML 中指定构造方 ...
- 全局程序集缓存gac中安装程序集_我就不信2W字把源码拆的这么碎,你还不明白mybatis缓存...
前言 不知道大家看到这张图感觉怎么样,不是难,一共也没有几个组件,但是真的让我想当头疼,因为在面试的时候,就这张图,对,你没看错,就这几个组件,那是让我相当难受啊 MyBatis中SQL执行的整体过程 ...
- apache缓存清理_深挖 Mybatis 源码:缓存模块
作者:AmyliaY 出自:Doocs开源社区 原文:my.oschina.net/doocs/blog/4549852 MyBatis 中的缓存分为一级缓存.二级缓存,但在本质上是相同的,它们使用的 ...
最新文章
- 2020牛客多校第3场:[Points Construction Problem + 思维题+构造]
- 概述:机器学习和大数据技术在信贷风控场景中的应用
- Codeforces Round #540 (Div. 3) A,B,C,D2,E,F1
- 判断一个点是否在矩形内部_高速公路专用矩形泄水管特点及安装注意事项
- PyTorch深度学习实践06
- css3 下边框缓缓划过_一篇文章带你了解CSS3按钮知识
- mybatis报错Type interface xxx.Dao is not known to the MapperRegistry
- java编译机制_java的编译机制
- 2-4实战分类之模型构建
- 【java】JOptionPane的几种方法的作用
- [02]基于webservice权限系统
- 黑盒测试--等价类划分
- MybatisPlus学习笔记
- SENTAURUS_2018_06
- 小米商城静态页面制做
- python stub_pycharm的python_stubs问题
- SSM整合尚硅谷Spring
- bzoj 4238: 电压 dfs
- windows socket相关接口整理
- Linux C 遍历目录下的所有文件
热门文章
- 中国.NET开发者峰会特别活动-基于k8s的微服务和CI/CD动手实践报名
- Apollo 配置中心:分布式部署
- .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
- 好代码是管出来的——使用GitHub
- 规模化微服务——《微服务设计》读书笔记
- ASP.NET Core Kestrel部署HTTPS
- dotnetCore增加MiddleWare的Run,Use Map MapThen四个扩展方法
- 【Envi风暴】基于ENVI平台提取ASTER DEM完整操作步骤(附案例数据)
- Android之获取到音视频的时长后按格式(00:00或者00:00:00)显示
- C/C++之函数返回值为指针或者是引用时常见错误总结