14、缓存
1.什么是缓存[cache]?
- 存在内存中的临时数据。 。存在内存中的临时数据。
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查 。从缓存中查询,从而提高查询效率,解决J高并发系统的性能问题。
- 从缓存中查询,从而提高查询效率,解决J高并发系统的性能问题。
2.为什么使用缓存?
- 减少和数据库的交互次数,减少系统开销,提高系统效率。
- 减少和数据库的交互次数,减少系统开销,提高系统效率.
3.什么样的数据能使用缓存?
- 经常查询并且不经常改变的数据。
- 经常查询并且不经常改变的数据.
Mybatis缓存
- MyBatis包含-一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
- MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存。
- 默认情况下,只有一级缓存开启。(SqlSessio)级别的缓存, 也称为本地缓存
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
- 为了提高扩展性, MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
一级缓存
一级缓存也叫本地缓存:SqlISession
- 与数据库同一次会话期间查询到的数据会放在本地缓存中。
- 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;
测试:
1、搭建环境
2、开启日志
<!--标准日志--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
3、测试查询两次相同的记录
4、查看日志输出
可以看到只执行了一次sql语句,第二次查询并没有走sql语句
Opening JDBC Connection Created connection 662822946. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2781e022] ==> Preparing: select * from user ; ==> Parameters: <== Columns: id, name, pwd <== Row: 1, zhangsan, 123 <== Row: 2, lisi, 1234 <== Row: 3, wangwu, 12345 <== Row: 4, zhangzhixi, zhixi158 <== Total: 4 User(id=1, name=zhangsan, pwd=123) User(id=2, name=lisi, pwd=1234) User(id=3, name=wangwu, pwd=12345) User(id=4, name=zhangzhixi, pwd=zhixi158) ---------------------------------------- User(id=1, name=zhangsan, pwd=123) User(id=2, name=lisi, pwd=1234) User(id=3, name=wangwu, pwd=12345) User(id=4, name=zhangzhixi, pwd=zhixi158) Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2781e022] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@2781e022]
缓存失效:
1.查询不同的东西
2.增删改操作,可能会改变原来的数据,所以必定会刷新缓存! .
3、查询不同的mapper.xml
4、手动清理缓存
sqlSession.clearCache();//手动清理缓存
二级缓存
MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。
默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
<cache/>
缓存机制:
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
- 如果当前会话关闭了,这个会话对应的一-级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
- 新的会话查询信息,就可以从二级缓存中获取内容;
- 不同的mapper查出的数据会放在自己对应的缓存(map) 中;
提示 二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。
步骤:
1、开启全局缓存(默认开启的)
<settings> <setting name="cacheEnabled" value="true"/> </settings>
2、使用二级缓存
<!--在Mapper.xml中使用二级缓存--> <cache/>
3、实体类实现序列化接口 Serializable
4、测试
@Test public void getUserAllTest(){ //两个SqlSession SqlSession sqlSession = MybatisUtil.getSqlSession(); SqlSession sqlSession2 = MybatisUtil.getSqlSession(); //两个mapper对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); List<User> userAll = mapper.getUserAll(); for (User user : userAll) { System.out.println(user); } //会话关闭了,一级缓存中的数据被保存到二级缓存中; sqlSession.close(); System.out.println("==============="); List<User> userAll2 = mapper2.getUserAll(); for (User user : userAll2) { System.out.println(user); } sqlSession2.close(); }
可以看到两个SqlSession只执行了一条sql语句:
==> Preparing: select * from user ; ==> Parameters: <== Columns: id, name, pwd <== Row: 1, zhangsan, 123 <== Row: 2, lisi, 1234 <== Row: 3, wangwu, 12345 <== Row: 4, zhangzhixi, zhixi158 <== Total: 4 User(id=1, name=zhangsan, pwd=123) User(id=2, name=lisi, pwd=1234) User(id=3, name=wangwu, pwd=12345) User(id=4, name=zhangzhixi, pwd=zhixi158) Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@17d677df] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@17d677df] Returned connection 399931359 to pool. =============== Cache Hit Ratio [com.zhixi.dao.UserMapper]: 0.5 User(id=1, name=zhangsan, pwd=123) User(id=2, name=lisi, pwd=1234) User(id=3, name=wangwu, pwd=12345) User(id=4, name=zhangzhixi, pwd=zhixi158)
Mybatis缓存原理:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话