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

2024年9月24日---关于MyBatis框架(3)

五 Mybatis的缓存

5.1 Mybatis缓存简介

缓存(cache):提前把数据存放到缓存当中,下一次再使用的时候,直接从缓存中拿,而不用再次去数据库中查询一次了。这样的优势在于:通过减少IO的⽅式,来提⾼程序的执⾏效率。 比如浏览器就有缓存功能…..

MyBatis的缓存:将select语句的查询结果放到缓存(内存)当中,下⼀次还是这条相同select语句的话,直接从缓存中取,不再查数据库。⼀⽅⾯是减少了IO,另⼀⽅⾯不再执⾏繁琐的查找算法;效率⼤⼤提升。

mybatis缓存包括:

  • ⼀级缓存:将查询到的数据存储到SqlSession中。

  • ⼆级缓存:将查询到的数据存储到SqlSessionFactory中。

  • 集成其它第三⽅的缓存:⽐如EhCache【Java语⾔开发的】、Memcache【C语⾔开发的】 等。

⚠️ 缓存只针对于DQL语句,也就是说缓存机制只对应select语句。

5.2 一级缓存

一级缓存的范围是SqlSession

  • ⼀级缓存默认是开启的,不需要做任何配置。

  • 原理:只要使⽤同⼀个SqlSession对象执⾏同⼀条SQL语句,就会⾛缓存。

什么时候不走缓存

  • 第⼀种:不同的SqlSession对象。

  • 第⼆种:查询条件变化了。

什么时候缓存失效

  • ①第⼀次查询和第⼆次查询之间,执行了clearCache()方法,⼿动清空了⼀级缓存

  • ②第⼀次查询和第⼆次查询之间,执⾏了增、删、改操作

5.3 二级缓存

⼆级缓存的范围是SqlSessionFactory对象。使⽤⼆级缓存需要具备以下⼏个条件

  • ①全局性地开启或关闭所有映射器配置⽂件中已配置的任何缓存。默认就是true,⽆需设置(默认二级缓存就是开启的)!

     <setting name="cacheEnabled" value="true">
  • ②在需要使⽤⼆级缓存的SqlMapper.xml⽂件中添加一个标签:<catche />

  • ③使⽤⼆级缓存的实体类对象必须是可序列化的,也就是必须实现java.io.Serializable接⼝

  • ④SqlSession对象关闭或提交之后,⼀级缓存中的数据才会被写⼊到⼆级缓存当中;此时⼆级缓存才可⽤。

⼆级缓存的失效:

  • 只要两次查询之间出现了增、删、改操作,⼆级缓存就会失效。【当然⼀级缓存也会失效】!

二级缓存相关配置

① eviction:指定从缓存中移除某个对象的淘汰算法。(默认采⽤LRU策略)

LRU:Least Recently Used。最近最少使⽤,优先淘汰在间隔时间内使⽤频率最低的对象。(其实还有⼀种淘汰算法LFU,最不常⽤)
FIFO:First In First Out。⼀种先进先出的数据缓存器,先进⼊⼆级缓存的对象最先被淘汰。
SOFT:软引⽤,淘汰软引⽤指向的对象。具体算法和JVM的垃圾回收算法有关。
WEAK:弱引⽤,淘汰弱引⽤指向的对象。具体算法和JVM的垃圾回收算法有关。

② flushInterval:⼆级缓存的刷新时间间隔,单位毫秒(刷新了也会使原来的缓存失效)。如果没有设置,就代表不刷新缓存,只要内存⾜够⼤,⼀ 直会向⼆级缓存中缓存数据,除⾮执⾏了增删改。

③size:设置⼆级缓存中最多可存储的java对象数量,默认值1024。

④readOnly

true: 只读缓存,多条相同的sql语句执⾏之后返回的对象是共享的同⼀个,性能好。但是多线程并发可能会存在安全问题。
false:读写缓存,多条相同的sql语句执⾏之后返回的对象是副本,调⽤了clone⽅法。性能⼀般,但安全。

5.4 Mybatis缓存查询顺序

  • 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用

  • 如果二级缓存没有命中,再查询一级缓存

  • 如果一级缓存也没有命中,则查询数据库

  • SqlSession管必须之后,一级缓存中的数据会写入二级缓存

5.5 MyBatis集成第三方缓存EhCache

mybatis对外提供了接⼝,也可以集成第三⽅的缓存组件;⽐如EhCache、Memcache等。 EhCache是Java写的、Memcache是C语⾔写的,所以mybatis集成EhCache较为常⻅,按照以下步骤操作,就可以完成集成

第⼀步:在pom.xml配置中引⼊MyBatis整合ehcache的依赖

ehcache需要slf4j的⽇志组件,log4j不好使!

<!--mybatis集成ehcache的组件-->
<dependency>
   <groupId>org.mybatis.caches</groupId>
   <artifactId>mybatis-ehcache</artifactId>
   <version>1.2.2</version>
</dependency>
​
​
<dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.2.11</version>
   <scope>test</scope>
</dependency>

第⼆步:在类的根路径下(resources)新建ehcache.xml⽂件,并提供以下配置信息。

<?xml version="1.0" encoding="UTF-8"?>
​
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
   <!--磁盘存储:将缓存中暂时不使⽤的对象,转移到硬盘,类似于Windows系统的虚拟内存-->
   <diskStore path="D:/ehcache"/>
​
   <defaultCache eternal="false" 
                 maxElementsInMemory="1000" 
                 ma
                 overflowToDisk="false"
                 diskPersistent="false" 
                 timeToIdleSeconds="0" 
                 timeToLiveSeconds="600"
                 memoryStoreEvictionPolicy="LRU"/>
</ehcache>

第三步:修改CarMapper.xml⽂件中的标签,添加type属性,引入EhcacheCache

<?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.bjpowernode.mybatis.mapper.CarMapper">
   <!--集成EhcacheCache组件-->
   <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
   <select id="selectById2" resultType="Car">
      select * from t_car where id = #{id}
   </select>
</mapper>

第四步:编写测试程序使⽤,代码还是和上面使用二级缓存的测试代码相同,效果展示也是相同的,都是第一次命中率是0.0,第二次命中率是0.5

六 MyBatis的逆向工程

七 Mybatis日志组件

7.1 Mybatis常用的日志组件

  • SLF4J

  • LOG4J

  • LOG4J2

  • STDOUT_LOGGING: 标准日志,Mybatis框架本身已经实现了这种日志,我们只需要使用<setting>标签开启日志即可。

7.2 开启日志输出:

<!--设置日志输出组件-->
<settings>
   <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
  • STDOUT_LOGGING我们可以直接使用,但是如果想使用SLF4J等第三方日志组件,需要引入相应jar包。

  • 注意: 这个标签必须在<properties></properties><typeAliases></typeAliases>前,这是dtd对xml文件的约束规范。

7.3 第三方日志组件的使用(SLF4J)

第一步:引入相应jar包logback

<dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.2.11</version>
   <scope>test</scope>
</dependency>

第二步:引入logback所必须的xml配置文件。这个xml文件必须在类的根路径下,文件名必须是logback.xml。

<?xml version="1.0" encoding="UTF-8"?>
​
<configuration debug="false">
     <!--定义⽇志⽂件的存储地址-->
     <property name="LOG_HOME" value="/home"/>
     
     <!-- 控制台输出 -->
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
         <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
             <!--格式化输出:%d表示⽇期,%thread表示线程名,%-5level:级别从左显示5 个字符宽度%msg:⽇志消息,%n是换⾏符-->
             <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
         </encoder>
     </appender>
    
     <!-- 按照每天⽣成⽇志⽂件 -->
     <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <!--⽇志⽂件输出的⽂件名-->
             <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
             <!--⽇志⽂件保留天数-->
             <MaxHistory>30</MaxHistory>
         </rollingPolicy>
         
         <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
             <!--格式化输出:%d表示⽇期,%thread表示线程名,%-5level:级别从左显示5 个字符宽度%msg:⽇志消息,%n是换⾏符-->
             <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
         </encoder>
         
         <!--⽇志⽂件最⼤的⼤⼩-->
         <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
             <MaxFileSize>100MB</MaxFileSize>
         </triggeringPolicy>
         
     </appender>
     
     <!--mybatis log configure-->
     <logger name="com.apache.ibatis" level="TRACE"/>
     <logger name="java.sql.Connection" level="DEBUG"/>
     <logger name="java.sql.Statement" level="DEBUG"/>
     <logger name="java.sql.PreparedStatement" level="DEBUG"/>
     <!-- ⽇志输出级别,logback⽇志级别包括五个:TRACE < DEBUG < INFO < WARN < ER
    ROR -->
     <root level="DEBUG">
         <appender-ref ref="STDOUT"/>
         <appender-ref ref="FILE"/>
     </root>
</configuration>
​

第三步:开启日志输出:

<!--设置日志输出组件-->
<settings>
   <setting name="logImpl" value="SLF4J"/>
</settings>

http://www.kler.cn/news/317897.html

相关文章:

  • Linux使用Clash,clash-for-linux
  • OpenCV多通道图像混合(六)
  • 【Linux 从基础到进阶】 QEMU 虚拟化配置与优化
  • OpenAI最新GPT-o1-preview测评
  • 关于事务的一些梳理
  • Springboot+Shiro+Mybatis+mysql实现权限安全认证
  • 深入解析:高性能 SSE 服务器的设计与实现
  • linux中crontab工具详解
  • React-Native 中使用 react-native-image-crop-picker 在华为手机上不能正常使用拍照功能
  • SQL常用技巧总结
  • ​‌GAS系统​
  • 【Kubernetes】常见面试题汇总(三十六)
  • OMRON欧姆龙通讯模块CI541V1
  • 网络安全:构建数字世界的坚固防线
  • MVCC机制解析:提升数据库并发性能的关键
  • Golang如何优雅的退出程序
  • MyBatis错误处理与日志
  • golang学习笔记31——golang 怎么实现枚举
  • 力扣2563.统计公平数对的数目
  • 【chromedriver编译-绕过selenium机器人检测】
  • st7735 stm32f103 lvgl调试记录3,spi篇
  • vue3ElementPlus使两个日期联动控制(限制结束时间为开始时间的一个月)
  • fastadmin本地安装插件提示”请从官网渠道下载插件压缩包(code:2)(code:1)“
  • iPhone 16 开始支持全新的 JPEG XL 格式
  • API 架构(RPC和RESTful)
  • 跳转页面(持续更新...)
  • 软件架构设计原则
  • mysql如何替换数据库所有表中某些字段含有的特定值
  • 虚拟机centos_7 配置教程(镜像源、配置centos、静态ip地址、Finalshell远程操控使用)
  • 目标检测基本知识