MyBatis-05

MyBatis-05

一、缓存简介

缓存(Cache),指的是将原本从数据库中读出来的数据放入内存中保存起来,下一次访问同样的数据时,直接从内存中进行读取,不再去查询数据库。因为大多数情况下,客户端执行的大多是查询的操作,因此,我们可以在客户端与服务器之间或者服务器与数据库之间加上一层数据缓存层,用来提高查询效率

优点:

  • 减少了对数据库的读操作,数据库的压力降低
  • 加快了响应速度

缺点:

  • 因为内存断电就清空数据,存放到内存中的数据可能丢失
  • 缓存中的数据可能与数据库中数据不一致
  • 内存的成本高
  • 内存容量相对硬盘小

二、一级缓存

在MyBatis中一级缓存也被叫做本地缓存

  • 与数据库同一会话期间将查询到的数据放在本地缓存
  • 在以后如果需要同样的数据,就会直接去本地缓存中拿,如果没有则会再次去查询数据库
  • 一级缓存的作用域为SqlSession创建到SqlSession关闭

一级缓存实现:

Mapper接口:
public interface UserMapper {

    User getUser(@Param("uid") long id);

}
Mapper文件:
<?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">
<!--namespace:对应数据访问层的接口-->
<mapper namespace="com.jack.dao.UserMapper">
    <select id="getUser" parameterType="long" resultType="user">
        select * from test.user where id = #{uid}
    </select>
</mapper>
单元测试:
@Test
public void testCache1(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    System.out.println(mapper.getUser(1));
    System.out.println("=======================");

    System.out.println(mapper.getUser(1));
    sqlSession.close();
}
输出:

在这里插入图片描述

结论:

从输出中可以看出只从数据库中读取了一次,第二次读取相同数据时直接从缓存中取得

三、二级缓存

在MyBatis中一级缓存也被叫做全局缓存

  • 基于namespace命名空间级别的缓存,一个命名空间(一个Mapper文件)对应一个二级缓存
  • 作用域比一级缓存广,即使一个会话关闭,启动另一个会话后再查询相同的数据仍然会从缓存中读取
  • 工作机制:
    • 一个会话查询一条数据,该数据被保存在当前会话的一级缓存中
    • 当前会话结束后,一级缓存将不复存在,数据将从一级缓存迁移到mapper文件对应的二级缓存中
    • 一个新的对话开启,读取相同的数据时,会从对应mapper文件的二级缓存中读取

二级缓存实现:

首先在config文件中配置settings允许全局缓存:
<setting name="cacheEnabled" value="true"/>
在对应的Mapper文件中添加全局缓存开启标签:
<cache/>
单元测试:
@Test
public void testCache2(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    System.out.println(mapper.getUser(1));
    sqlSession.close();

    System.out.println("=======================");

    SqlSession sqlSession1 = MyBatisUtils.getSqlSession();
    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);

    System.out.println(mapper1.getUser(1));
    sqlSession1.close();
}
输出:

在这里插入图片描述

结论:

从上面的输出可以看出二级缓存作用域更强更广

四、MyBatis缓存原理

一张图即可说明:

在这里插入图片描述

解释:

  • 用户查询先从二级缓存中查找,若有,则直接返回,若无,去一级缓存查
  • 一级缓存中若有,则直接返回,若无,去数据库中查询
  • 查询完毕后将保存至一级缓存,若此时会话关闭,则将缓存提交至对应Mapper的二级缓存中

至此,MyBatis主要部分学习完毕,有任何问题可以在评论区提出或私信博主,一起讨论,一起进步!

相关文章:

  • MyBatis-01

    • 什么是MyBatis
    • 为什么要用MyBatis
    • 如何使用MyBatis?
  • MyBatis-02

    • 增删改查实现
    • Map以及模糊查询
    • 配置属性优化
    • 配置别名优化
    • 配置映射器说明
    • 生命周期以及作用域
    • ResultMap结果集映射
  • MyBatis-03

    • 日志实现
    • 分页实现
    • 注解开发
    • MyBatis执行流程
    • 通过注解实现增删改查
    • LomBok使用
  • MyBatis-04

    • 复杂查询环境搭建
    • 多对一处理
    • 一对多处理
    • 动态SQL环境搭建
      • IF标签
      • 常用标签
        • WHERE
        • CHOOSE
        • WHEN
        • TRIM
        • OTHERWISE
        • SET
      • ForEach标签
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过 Java 中的 SimpleDateFormat 将当前日期转换为字符串形式,然后将其作为参数传递给 MyBatis 的映射文件中的 SQL 语句。以下是一些示例代码: ```java // 获取当前日期 Date now = new Date(); // 将日期格式化为字符串形式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String dateStr = sdf.format(now); // 调用第一个 SQL 语句 List<Result> results1 = sqlSession.selectList("zdyjkzbjl.selectByTime1", dateStr); // 调用第二个 SQL 语句 List<Result> results2 = sqlSession.selectList("zdyjkzbjl.selectByTime2", dateStr); // 调用第三个 SQL 语句 List<Result> results3 = sqlSession.selectList("zdyjkzbjl.selectByTime3", dateStr); ``` 在这里,"zdyjkzbjl" 是映射文件中的命名空间,"selectByTime1"、"selectByTime2" 和 "selectByTime3" 分别是三个 SQL 语句的 id,"dateStr" 是当前日期的字符串形式,作为 SQL 语句的参数传递。在映射文件中,对应的 SQL 语句可以这样写: ```sql <!-- 第一个 SQL 语句 --> <select id="selectByTime1" resultType="Result"> select * from zdyjkzbjl where jsbh=#{jsbh} and TO_CHAR(pbrq, 'yyyy-mm-dd')=#{dateStr} and bc='1' and TO_CHAR(jbsj, 'yyyy-mm-dd hh24:MI')<>'2023-05-23 07:50' and TO_CHAR(jiaobsj, 'yyyy-mm-dd hh24:MI')<>'2023-05-23 19:50' and TO_CHAR(now(), 'yyyy-mm-dd hh24:MI:SS') between '2023-05-23 07:50:00' and '2023-05-23 17:00:00' </select> <!-- 第二个 SQL 语句 --> <select id="selectByTime2" resultType="Result"> select * from zdyjkzbjl where jsbh=#{jsbh} and TO_CHAR(pbrq, 'yyyy-mm-dd')=#{dateStr} and bc='2' and TO_CHAR(jbsj, 'yyyy-mm-dd hh24:MI')='2023-05-23 19:50' and TO_CHAR(jiaobsj, 'yyyy-mm-dd hh24:MI')='2023-05-24 01:50' and TO_CHAR(now(), 'yyyy-mm-dd hh24:MI:SS') between '2023-05-23 17:00:00' and '2023-05-24 01:30:00' </select> <!-- 第三个 SQL 语句 --> <select id="selectByTime3" resultType="Result"> select * from zdyjkzbjl where jsbh=#{jsbh} and TO_CHAR(pbrq, 'yyyy-mm-dd')=#{dateStr} and bc='3' and TO_CHAR(jbsj, 'yyyy-mm-dd hh24:MI')<>'2023-05-24 01:50' and TO_CHAR(jiaobsj, 'yyyy-mm-dd hh24:MI')<>'2023-05-24 07:50' and TO_CHAR(now(), 'yyyy-mm-dd hh24:MI:SS') between '2023-05-24 01:30:00' and '2023-05-24 07:50:00' </select> ``` 在 SQL 语句中,使用 #{dateStr} 来引用 Java 代码中传递的参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值