不能吧,你不能这样,都最后了-------sql和缓存(“最易懂得MyBatis学习”)(下)

简介: 十三、缓存1. 简介2. Mybatis缓存3. 一级缓存3.1 测试步骤:3.2 缓存失效得情况3.3 小结4. 二级缓存4.1 简介4.2 开启步骤4.3 测试4.4 小结5. 缓存原理6. 自定义缓存-Ehcache

十三、缓存

1. 简介


查询-->需要连接数据库,耗资源
  一次查询的结果,给他暂存一个可以直接取到的地方-->内存:缓存
我们再次查询相同数据的时候,直接走缓存,就不用走数据库了 

1.什么是缓存[Cache]?


  • 存在内存中的临时数据


  • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。


2.为什么要使用缓存?


  • 减少和数据库的交互次数,减少系统开销,提高系统效率


3.什么样的数据能使用缓存?


  • 经常查询并且不经常改变的数据


2. Mybatis缓存


1.Mybatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大地提升查询效率。


2.Mybatis系统中默认定义了两级缓存:一级缓存和二级缓存


  • 默认情况下,只有一级缓存开启。(Sqlsession级别的缓存,也称为本地缓存)


  • 二级缓存需要手动开启和配置,是基于namespace级别的缓存


  • 为了提高扩展性,mybatis定义了缓存接口,我们可以通过实现Cache接口来自定义二级缓存。


3. 一级缓存


  • 一级缓存也叫本地缓存:SqlSession


  • 与数据库同一次会话期间查询到得数据会放在本地缓存中


  • 以后如果需要获取相同得数据,直接从换从中拿,没必要再去查询数据库


3.1 测试步骤:


1. 开启日志


在核心配置文件中

<settings>
    <!--标准的日志工厂实现-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

2.测试再一个Session中查询两次相同得记录

@Test
public void queryUserByIdTest(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = mapper.queryUserById(1);
    System.out.println(user);
    System.out.println("========");
    User user1 = mapper.queryUserById(1);
    System.out.println(user1);
    sqlSession.close();
}

3.查看日志输出

微信图片_20211230140622.png


3.2 缓存失效得情况


  • 查询不同得东西


  • 增删改操作可能会改变原来得数据,所以必定会刷新缓存


  • 比如说在查两个相同的用户,中间插一个修改用户的操作


  • 查询不同Mapper.xml


  • 手动清理缓存


sqlSession.clearCache();//手动清理缓存

3.3 小结


一级缓存默认是开启的,只在一次sqlSession中有效,也就是拿到连接到关闭连接这个区间


一级缓存就相当于一个map


4. 二级缓存


4.1 简介


4.2 开启步骤


1.开启全局缓存


虽然默认就是true但是还是需要显示的开启一下,增强可读性


微信图片_20211230140907.png


在核心配置文件中

<settings>
    <!--显示的开启全局缓存-->
    <setting name="cacheEnabled" value="true"/>
</settings>


2.要启用二级缓存需要在sql映射文件中添加一行代码


<!--在当前Mapper.xml中开启二级缓存-->
<cache/>

也可以自定义一些参数


<!--官网上是这个。加上会有一些设定,比如先进先出,60秒,512个引用,只读为true-->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

还可以在你想要的地方关闭缓存,只需要在sql语句标签下添加下面的代码


微信图片_20211230141049.png

4.3 测试


1. 如果没有加二级缓存,查询两个sqlSession是会进入两次数据库的


@Test
public void queryUserByIdTest(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    SqlSession sqlSession2 = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
    User user = mapper.queryUserById(1);
    System.out.println(user);
    User user1 = mapper2.queryUserById(1);
    System.out.println(user1);
    sqlSession.close();
    sqlSession2.close();
}

微信图片_20211230141150.png

2.如果开启了二级缓存

@Test
public void queryUserByIdTest(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    SqlSession sqlSession2 = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = mapper.queryUserById(1);
    System.out.println(user);
    sqlSession.close();
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
    User user1 = mapper2.queryUserById(1);
    System.out.println(user1);
    System.out.println(user == user1);
    sqlSession2.close();
}

微信图片_20211230141530.png


3.问题:


我们需要将实体类序列化,否则就会报错

Caused by:java.io.NotSerializableException:com.hxl.pojo.User


我们需要在实体类后加上implements Serializable

@Data
public class User implements Serializable {
    private int id;
    private String name;
    private String pwd;
}


4.4 小结


  1. 只要开启了二级缓存,在同一个Mapper下就有效


  1. 所有的数据都会先放在一级缓存中


  1. 只有当会话提交,或者关闭的时候,才会提交到二级缓存中


  1. 实体类要序列化


5. 缓存原理

微信图片_20211230141657.png


6. 自定义缓存-Ehcache


Ehcache是一种广泛使用的开源Java分布式缓存,主要面向通用缓存


要在程序中使用Ehcache,先要导包

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.1</version>
</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">
    <!--
    -->
    <diskStore path="./tmpdir/Tmp_EhCache"/>
    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>
    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
</ehcache>

在需要的Mapper.xml下

<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

测试微信图片_20211230141827.png

相关文章
|
3月前
|
缓存 Java 数据库连接
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
文章介绍了MyBatis的缓存机制,包括一级缓存和二级缓存的配置和使用,以及如何整合第三方缓存EHCache。详细解释了一级缓存的生命周期、二级缓存的开启条件和配置属性,以及如何通过ehcache.xml配置文件和logback.xml日志配置文件来实现EHCache的整合。
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
|
2天前
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
8天前
|
SQL XML Java
mybatis实现动态sql
MyBatis的动态SQL功能为开发人员提供了强大的工具来应对复杂的查询需求。通过使用 `<if>`、`<choose>`、`<foreach>`等标签,可以根据不同的条件动态生成SQL语句,从而提高代码的灵活性和可维护性。本文详细介绍了动态SQL的基本用法和实际应用示例,希望对您在实际项目中使用MyBatis有所帮助。
28 11
|
22天前
|
缓存 Java 数据库连接
MyBatis缓存机制
MyBatis提供两级缓存机制:一级缓存(Local Cache)默认开启,作用范围为SqlSession,重复查询时直接从缓存读取;二级缓存(Second Level Cache)需手动开启,作用于Mapper级别,支持跨SqlSession共享数据,减少数据库访问,提升性能。
27 1
|
25天前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
41 4
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
1月前
|
SQL 安全 前端开发
Web学习_SQL注入_联合查询注入
联合查询注入是一种强大的SQL注入攻击方式,攻击者可以通过 `UNION`语句合并多个查询的结果,从而获取敏感信息。防御SQL注入需要多层次的措施,包括使用预处理语句和参数化查询、输入验证和过滤、最小权限原则、隐藏错误信息以及使用Web应用防火墙。通过这些措施,可以有效地提高Web应用程序的安全性,防止SQL注入攻击。
54 2
|
1月前
|
SQL 缓存 Java
MyBatis如何关闭一级缓存(分注解和xml两种方式)
MyBatis如何关闭一级缓存(分注解和xml两种方式)
82 5
|
1月前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
55 10