您的位置:首页 > 汽车 > 新车 > 《网站推广策划》_平面设计包括哪些内容_域名申请哪家好_龙岗网站建设

《网站推广策划》_平面设计包括哪些内容_域名申请哪家好_龙岗网站建设

2025/3/10 23:17:02 来源:https://blog.csdn.net/m0_74124657/article/details/146103668  浏览:    关键词:《网站推广策划》_平面设计包括哪些内容_域名申请哪家好_龙岗网站建设
《网站推广策划》_平面设计包括哪些内容_域名申请哪家好_龙岗网站建设

前言

为什么要学习Mybatis 缓存机制?

学习Mybatis 缓存机制,可以有效解决 数据库的压力,提高数据库的性能。

例如:你要  对tb_user 表 ,查询 所有用户的信息,并且多次查询所有用户信息。我们知道第一次查询表信息流程是 ,执行 sql 查询语句,找到存储在数据库的目标数据【在硬盘】,最后得到这些数据。那如果第二次查询,我们依旧如此,这般循环往复,如果是存储很多数据的数据库,这样一次查询,耗时是很长的,且会数据库的性能。

思考,当 第一次得到查询数据或者进行其他的操作后,能否把最终的数据临时存储在一个地方。当第二次执行相同的sql 语句时,传递相同的参数,可以直接从这地方获得,不再需要从 数据库进行二次查询。这样不仅节省了时间,还提高了性能。-------Mybatis 缓存机制 的功能


Mybatis一级缓存

一级缓存的功能

一级缓存会将第一次执行SQL语句后查询到的结果存储在缓存中。这些数据会被暂存,以便后续的查询操作可以直接从缓存中读取,而无需再次访问数据库。

  • 一级缓存 是SqlSession 级别的缓存。如果同一个SqlSession 对象 多次执行完全相同的sql 语句,在第一次执行完成后, Mybatis 会将查询结果写入一级缓存中,此后如果程序没有执行插入,更新,删除操作,当第二次执行相同的查询语句,Mybatis 会直接 读取一级缓存中的数据,而不用再去数据库查询,从而提高数据库的查询效率。

例子

从 数据表 tb_book 中多次 查询 di=1 的图书信息,使用 一级缓存 。

注意:学习 一级缓存的核心 不仅仅理解 一级缓存是临时存储场所,而且始终与数据库存储的数据保持同步------这里具体表现为数据的一致性


数据一致性的真正含义

数据一致性是指在缓存机制中,缓存中的数据与数据库中的数据始终保持一致。具体来说,这意味着:

  1. 读取操作:当从缓存中读取数据时,缓存中的数据必须是最新的,与数据库中的数据完全一致。

  2. 写入操作:当数据库中的数据发生变化时(例如通过INSERTUPDATEDELETE操作),缓存中的数据必须及时更新或失效,以避免读取到过时的数据。


验证 数据的一致性

1 当执行相同的sql 语句时,获得相同的结果

2 存储在 一级缓存的数据,在数据库中也要存在,并且不会轻易被改变

demo(案例:验证 数据的一致性)

目的: 查询  id=1 时,图书信息

项目准备

tb_book 表 和与之对应的 实体类 Book 类

  • tb_book 表

  • 实体类 Book 类

添加 需要的依赖

  • mybatis 框架固定的依赖 + log4j 日志依赖 通过控制台直观看到整个过程
 <dependencies><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><!-- https://mvnrepository.com/artifact/log4j/log4j --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies>

log4j 日志依赖配套的log4j.properties 配置文件

# Set root logger level
log4j.rootLogger=DEBUG, stdout# Set the log output format
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

BookMapper 接口方法

    // 根据id查询图书public Book queryBookById(int id);// 更新图书public int updateBook(Book book);

正文

BookMapper.xml 映射文件

<?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="fs.mapper.BookMapper">
<!--    根据id 查询 图书信息--><select id="queryBookById" parameterType="int" resultType="fs.entity.Book">select * from tb_book where id = #{id}</select>
<!--    根据id 修改--><update id="updateBook" parameterType="fs.entity.Book">update tb_book set price = #{price},author = #{author},bookName = #{bookName} where id = #{id}</update>
</mapper>

BookTest 测试类

1  两次查询  id=1 时,图书信息
        // 第一次执行Book book = sqlSession.selectOne("queryBookById", 1);System.out.println(book);// 第二次执行 sqlSession.selectOne("queryBookById", 1);Book book1 = sqlSession.selectOne("queryBookById", 1);System.out.println(book1);

运行截图

发现

通过运行截图和 代码发现,之后使用同样的sql 语句和传递相同的参数,会从一级缓存中直接获得,不再经过数据库。


2 查询id=1 和第二次 id=2 图书信息

BookTest 测试类

运行截图

发现

即使第二次执行相同的sql 语句,如果传递不同的参数,不能从一级缓存中获得目标结果,只能通过数据库查询


3 第一次执行 id=1 的查询 图书信息 ,第二次执行 修改 id=1 的图书名,第三次查询id=1图书信息

BookTest 测试类

 // 第一次执行Book book = sqlSession.selectOne("queryBookById", 1);System.out.println(book);// 第二次更新int update = sqlSession.update("updateBook", new Book(1, "author", "Html基础","67"));sqlSession.commit();// 第二次执行 sqlSession.selectOne("queryBookById", 1);Book book1 = sqlSession.selectOne("queryBookById", 1);System.out.println(book1);sqlSession.close();

运行截图

最后我们发现:

一级缓存实质上是在内存开辟一个空间来存储数据的。

一级缓存不需要,我们手动创建或者设置的


Mybatis二级缓存

为什么要学习 Mybatis二级缓存?

学完一级缓存后,发现 在相同的Mapper 映射文件中使用相同的SQL语句,如果sqlSession不同,则两个sqlSession查询数据时,会查询数据两次,这样会降低数据库的查询效率。因此为了解决这个问题 使用 Mybatis二级缓存

Mybatis二级缓存 的优点

二级缓存 是一个跨多个 SqlSession 的共享缓存机制,它的作用范围比一级缓存更广泛。二级缓存可以显著提高系统的性能,因为它允许在多个会话之间共享缓存数据,从而减少对数据库的重复查询。


二级缓存的工作原理

  1. 查询流程

    • 当执行查询操作时,MyBatis 首先检查一级缓存。

    • 如果一级缓存中没有找到数据,则检查二级缓存。

    • 如果二级缓存中也没有找到数据,则查询数据库,并将结果存入二级缓存。

  2. 更新流程

    • 当执行数据更新操作(如 INSERTUPDATEDELETE)时,MyBatis 会清空相关的一级缓存和二级缓存,以确保数据一致性。


手动打开二级缓存的步骤

1 在主配置文件 mybatis-config .xml 开启二级 缓存的全局配置

    <settings>
<!--        开启日志--><setting name="logImpl" value="LOG4J"/>
<!--        开启二级缓存--><setting name="cacheEnabled" value="true"/>
</settings>

2 在 Mapper XML 文件中,使用 <cache> 标签配置二级缓存。

二级缓存一般是默认状态,可以实现的功能如下

1 映射文件所有的select 语句将会被缓存

2 映射文件中的所有的insert,update,delete 都会被刷新缓存

3 缓存会使用LRU算法回收

4 没有刷新间隔

5 缓存是可读可写的,但不被共享

以上是默认状态的特性,如果需要调整,可通过cache 元素的属性来实现

配置参数说明:
  • eviction:缓存回收策略。可选值包括:

    • FIFO(先进先出)

    • LRU(最近最少使用)

    • SOFT(软引用)

    • WEAK(弱引用)

  • flushInterval:缓存刷新间隔(毫秒)。默认值为不刷新。

  • size:缓存的最大存储对象数量。

  • readOnly:是否只读。如果设置为 true,则缓存中的数据被认为是只读的,可以提高性能,但不允许修改。


3 . 实体类实现 Serializable

4 BookTest测试类中 两次查询 id=1 的图书信息

package fs.Test;import fs.entity.Book;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;
import java.io.InputStream;public class BookTest {public static void main(String[] args) throws IOException {InputStream resource = Resources.getResourceAsStream("mybatis-confif.xml");SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resource);SqlSession sqlSession = build.openSession();SqlSession sqlSession1 = build.openSession();// 第一次执行Book book = sqlSession.selectOne("queryBookById", 3);System.out.println(book);sqlSession.close();// 第二次执行Book book1 = sqlSession1.selectOne("queryBookById", 3);System.out.println(book1);sqlSession1.close();}
}

运行截图

补充
  • 缓存命中率

缓存命中率的计算公式

缓存命中率通常通过以下公式计算: 缓存命中率=总查询次数缓存命中次数​

  • 缓存命中次数:从缓存中成功获取到数据的次数。

  • 总查询次数:所有查询操作的次数,包括从缓存中获取数据和从数据库中查询数据的次数。


示例

假设你进行了 10 次查询操作:

  • 3 次查询直接从缓存中获取到了数据(缓存命中)。

  • 7 次查询需要从数据库中查询数据(缓存未命中)。

那么缓存命中率为: 缓存命中率=103​=0.3 或 30%


MyBatis 中的缓存命中率

在 MyBatis 的日志中,你可以看到类似以下的输出:

DEBUG BookMapper:60 - Cache Hit Ratio [fs.mapper.BookMapper]: 0.0

这表示当前的缓存命中率为 0.0,即尚未有缓存命中。


为什么缓存命中率是 0.0?

  1. 缓存尚未生效

    • 如果是第一次查询,缓存尚未填充,因此命中率为 0。

    • 如果二级缓存未正确配置(如实体类未实现 Serializable 接口,或 <cache> 标签未正确设置),缓存可能不会生效。

  2. 查询条件不匹配

    • 缓存基于查询语句和参数进行匹配。如果查询语句或参数不同,即使使用了缓存,也可能无法命中。

  3. 缓存被清空

    • 如果在两次查询之间执行了数据更新操作(如 INSERTUPDATEDELETE),二级缓存可能会被清空,导致命中率为 0。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com