关闭页面特效

一级缓存&二级缓存

1|0一级缓存


1|1目标


  1. 为什么要缓存
  2. 一级缓存的使用

1|2缓存概述


为什么要使用缓存

如果每次访问数据库都去获取连接,查询数据库的记录,返回结果集,效率比较低。

缓存相当于服务器内存中一块区域,会缓存最近查询的SQL语句以及sql语句的查询结果,如果再次发送相同的SQL语句,mybatis就不再重新访问数据库,而是从内存中读取已经存在的数据返回给客户端。

使用缓存的目的:就是为了提升查询的速度

缓存的分类

在mybatis中缓存分成2类:

  1. 一级缓存
  2. 二缓缓存

缓存结构

  1. 一级缓存是默认打开的,会话级别缓存,只在一个会话中起作用。
  2. 二级缓存必须是手动开启,可以在各个会话之间共享数据

image-20230524172144589

1|3案例:一级缓存


一级缓存的范围:只在同一个会话中起作用,默认是自动开启的。

需求

通过同一个 sqlSession 对象,通过id查询2次,观察发出 sql 语句的次数。

步骤

  1. 在同一个测试方法中查询2次
  2. 输出用户信息

代码

package com.tyhxzy.test; import com.tyhxzy.dao.UserMapper; import com.tyhxzy.entity.User; import com.tyhxzy.utils.SqlSessionUtils; import org.apache.ibatis.session.SqlSession; /** * 使用一级缓存 */ public class TestFirstLevelCache { public static void main(String[] args) { //1.获取一个会话对象 SqlSession session = SqlSessionUtils.getSession(); //2.查询2次用户对象 UserMapper userMapper = session.getMapper(UserMapper.class); User user = userMapper.findUserById(1); System.out.println("名字:" + user.getUsername()); //3.第2次执行 User user2 = userMapper.findUserById(1); System.out.println("名字:" + user2.getUsername()); session.close(); } }

效果

DEBUG - ==> Preparing: select * from user where id=? DEBUG - ==> Parameters: 1(Integer) DEBUG - <== Total: 1 名字:孙悟空 名字:孙悟空

1|4一级缓存的分析


image-20230524172216472

1|5案例:一级缓存的清空


清空的目的:如果进行了增删改的操作,表中的记录有可能发生变化,缓存中的数据就是脏数据。

清空的方式: 只要执行了增删改的操作,提交事务,关闭会话操作会就自动清空一级缓存的数据

需求

  1. 第一次查询以后,提交会话
  2. 再进行第二次查询,观察查询结果

代码

package com.tyhxzy.test; import com.tyhxzy.dao.UserMapper; import com.tyhxzy.entity.User; import com.tyhxzy.utils.SqlSessionUtils; import org.apache.ibatis.session.SqlSession; /** * 使用一级缓存 */ public class TestFirstLevelCache { public static void main(String[] args) { //1.获取一个会话对象 SqlSession session = SqlSessionUtils.getSession(); //2.查询2次用户对象 UserMapper userMapper = session.getMapper(UserMapper.class); User user = userMapper.findUserById(1); System.out.println("名字:" + user.getUsername()); //清除缓存 session.clearCache(); //3.第2次执行 User user2 = userMapper.findUserById(1); System.out.println("名字:" + user2.getUsername()); session.close(); } }

效果

DEBUG - ==> Preparing: select * from user where id=? DEBUG - ==> Parameters: 1(Integer) DEBUG - <== Total: 1 名字:孙悟空 DEBUG - ==> Preparing: select * from user where id=? DEBUG - ==> Parameters: 1(Integer) DEBUG - <== Total: 1 名字:孙悟空

1|6小结


  1. 什么是一级缓存

    在同一个会话中起作用

  2. 如何清除一级缓存

    增删改,提交事务,关闭会话

2|0二级缓存


2|1目标


二级缓存的配置和使用

2|2概述


什么是二级缓存?

范围:在多个会话中起作用,如果有2个会话进行相同查询,就会使用缓存。

2|3步骤


  1. mybatis-config.xml开启二级缓存
<settings> <!-- 开启二级缓存 --> <setting name="cacheEnabled" value="true"/> </settings>
  1. 缓存的实体类要序列化
为什么要序列化?把内存中对象写到硬盘的文件中 因为二级缓存缓存的数据量可能非常大,服务器不会将所有的对象都放在内存中,有些数据放在硬盘的文件中。 public class User implements Serializable
  1. 创建UserMapper.xml
    1. 开启二级缓存
    2. 编写查询语句
<?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" > <mapper namespace="com.tyhxzy.dao.UserMapper"> <!-- 开启二级缓存:对当前配置文件中所有的查询进行二级缓存 --> <cache/> <select id="findUser" resultType="com.tyhxzy.entity.User"> select * from user where id=#{id} </select> </mapper>

2|4标签作用


  1. 所有在映射文件里的 select 语句都将被缓存。
  2. 所有在映射文件里 insert,update 和 delete 语句会清空缓存。
  3. 缓存使用“最近很少使用”算法来回收
  4. 每个缓存可以存储 1024 个列表或对象的引用。
  5. 缓存获取的对象不是共享的且对调用者是安全的,不会有其它的调用者或线程潜在修改。

2|5案例:二级缓存


需求

通过两个 sqlSession 对象,执行两次通过id查询用户,观察发出 sql 语句的次数。

步骤

  1. 创建一个会话查询1条记录,关闭会话
  2. 再创建一个会话查询1条记录,关闭会话
  3. 观察命中的概率

代码

package com.tyhxzy.test; import com.tyhxzy.dao.UserMapper; import com.tyhxzy.entity.User; import com.tyhxzy.utils.SqlSessionUtils; import org.apache.ibatis.session.SqlSession; /** * 测试二级缓存 */ public class TestSecondCache { public static void main(String[] args) { //创建第一个会话 SqlSession s1 = SqlSessionUtils.getSession(); //得到代理对象 UserMapper userMapper = s1.getMapper(UserMapper.class); User u1 = userMapper.findUser(1); System.out.println(u1); s1.close(); //创建第二个会话 SqlSession s2 = SqlSessionUtils.getSession(); //得到代理对象 UserMapper userMapper2 = s2.getMapper(UserMapper.class); User u2 = userMapper2.findUser(1); System.out.println(u2); s2.close(); } }

效果

DEBUG - ==> Preparing: select * from user where id=? DEBUG - ==> Parameters: 1(Integer) DEBUG - <== Total: 1 User{id=1, username='孙悟空', birthday=1980-10-24, sex='男', address='花果山水帘洞'} DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a556333] DEBUG - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a556333] DEBUG - Returned connection 710239027 to pool. 命中率50% DEBUG - Cache Hit Ratio [com.tyhxzy.dao.UserMapper]: 0.5 User{id=1, username='孙悟空', birthday=1980-10-24, sex='男', address='花果山水帘洞'}

2|6二级缓存分析


  1. 第1个会话查询完成以后,将查询的结果放在二级缓存中
  2. 如果有其它的会话进行相同的查询,会直接在二级缓存中读取,不再访问数据库
  3. 如果有会话执行了增删改,提交事务的方法,就会清空缓存

image-20230524172255887

2|7小结


  1. 在核心配置文件中开启二级缓存:cacheEnabled=true
  2. 对缓存实体类序列化
  3. 在配置文件中开启缓存<cache/>

__EOF__

作  者YXH
出  处https://www.cnblogs.com/YxinHaaa/p/17430108.html
关于博主:编程路上的小学生,热爱技术,喜欢专研。评论和私信会在第一时间回复。或者直接私信我。
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!

posted @   YxinHaaa  阅读(130)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
0
0
关注
跳至底部
点击右上角即可分享
微信分享提示