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

10_缓存-2_二级缓存

二级缓存是以namespace为标记的缓存,可以是由一个SqlSessionFactory创建的SqlSession之间共享缓存数据。默认并不开启。下面的代码中创建了两个SqlSession,执行相同的SQL语句,尝试让第二个SqlSession使用第一个SqlSession查询后缓存的数据。要求实体类必须实现序列化接口

接口

public interface EmpMapper {
    Emp findByEmpno(int empno);
}

映射文件

<mapper namespace="com.msb.mapper.EmpMapper">
    <cache/>
    <select id="findByEmpno" resultType="emp" useCache="true" flushCache="false">
        select * from emp where empno =#{empno}
    </select>
</mapper>

测试 代码

package com.msb.test;
import com.msb.mapper.EmpMapper;
import com.msb.pojo.Emp;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/**
 * @Author: Ma HaiYang
 * @Description: MircoMessage:Mark_7001
 */
public class Test3 {
    private SqlSession sqlSession;
    private SqlSession sqlSession2;
    @Before
    public void init(){
        SqlSessionFactoryBuilder ssfb =new SqlSessionFactoryBuilder();
        InputStream resourceAsStream = null;
        try {
            resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        SqlSessionFactory factory=ssfb.build(resourceAsStream) ;
        sqlSession=factory.openSession();
        sqlSession2=factory.openSession();
    }
    @Test
    public void testFindDeptByDetpno()   {
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.findByEmpno(7521);
        System.out.println(emp);
        // SqlSession提交之后,才会将查询的结果放入二级缓存
        sqlSession.commit();
        EmpMapper mapper2 = sqlSession2.getMapper(EmpMapper.class);
        Emp emp2 = mapper2.findByEmpno(7521);
        System.out.println(emp2);
    }
    @After
    public void release(){
        // 关闭SQLSession
        sqlSession.close();
        sqlSession2.close();
    }
}
 

注意其中的commit(),执行该命令后才会将该SqlSession的查询结果从一级缓存中放入二级缓存,供其他SqlSession使用。另外执行SqlSession的close()也会将该SqlSession的查询结果从一级缓存中放入二级缓存。两种方式区别在当前SqlSession是否关闭了。

执行结果显示进行了两次对数据库的SQL查询,说明二级缓存并没有开启。需要进行如下步骤完成开启。


1)    全局开关:在sqlMapConfig.xml文件中的<settings>标签配置开启二级缓存


<settings>

    <setting name="cacheEnabled" value="true"/>

</settings>

cacheEnabled的默认值就是true,所以这步的设置可以省略。

2)    分开关:在要开启二级缓存的mapper文件中开启缓存:


<mapper namespace="com.msb.mapper.EmployeeMapper">

    <cache/>
</mapper>

3)    二级缓存未必完全使用内存,有可能占用硬盘存储,缓存中存储的JavaBean对象必须实现序列化接口,


public class Emp implements  Serializable {  }

经过设置后,查询结果如图所示。发现第一个SqlSession会首先去二级缓存中查找,如果不存在,就查询数据库,在commit()或者close()的时候将数据放入到二级缓存。第二个SqlSession执行相同SQL语句查询时就直接从二级缓存中获取了。

注意:

1)    MyBatis的二级缓存的缓存介质有多种多样,而并不一定是在内存中,所以需要对JavaBean对象实现序列化接口。

2)    二级缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响

3)    加入Cache元素后,会对相应命名空间所有的select元素查询结果进行缓存,而其中的insert、update、delete在操作是会清空整个namespace的缓存。

4)    cache 有一些可选的属性 type, eviction, flushInterval, size, readOnly, blocking。

<cache type="" readOnly="" eviction=""flushInterval=""size=""blocking=""/>

5)    如果在加入Cache元素的前提下让个别select 元素不使用缓存,可以使用useCache属性,设置为false。useCache控制当前sql语句是否启用缓存  flushCache控制当前sql执行一次后是否刷新缓存


 
<select id="findByEmpno" resultType="emp" useCache="true" flushCache="false">

相关文章:

  • 【FAQ】申请Health Kit权限的常见问题及解答
  • Servlet生命周期和线程安全
  • 【C++进阶】C++11新特性下篇(万字详解)
  • 一文读懂于Zebec生态中的潜在收益方式
  • 蓝桥杯有必要参赛吗?
  • 移植MQTT-C库(附源码)
  • 创建Series()对象--pandas
  • 【Linux】软件包管理器yum
  • 算法刷题打卡第49天:排序数组---计数排序
  • 【Linux】低级IO
  • 【Linux】shell命令以及运行原理
  • 【解决】Unity Player Log 自生成造成磁盘满占用率问题
  • 犀牛插件开发-基础核心-技术概览-总体架构-教程
  • 看2022年卡塔尔世界杯有感
  • 小黑被劝退了,生活学习依然继续的leetcode之旅:572. 另一棵树的子树
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【comparator, comparable】小总结
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • Invalidate和postInvalidate的区别
  • JS函数式编程 数组部分风格 ES6版
  • Lucene解析 - 基本概念
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • 工作手记之html2canvas使用概述
  • 简单易用的leetcode开发测试工具(npm)
  • 码农张的Bug人生 - 见面之礼
  • 你不可错过的前端面试题(一)
  • 前端攻城师
  • 新版博客前端前瞻
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • # 数据结构
  • #{}和${}的区别是什么 -- java面试
  • #LLM入门|Prompt#3.3_存储_Memory
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (论文阅读30/100)Convolutional Pose Machines
  • .chm格式文件如何阅读
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET 回调、接口回调、 委托
  • .sh
  • @GetMapping和@RequestMapping的区别
  • @JsonFormat与@DateTimeFormat注解的使用
  • @JsonSerialize注解的使用
  • @Validated和@Valid校验参数区别
  • [ IO.File ] FileSystemWatcher
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [2010-8-30]
  • [20161214]如何确定dbid.txt
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [asp.net core]project.json(2)
  • [BZOJ4566][HAOI2016]找相同字符(SAM)