MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选:

package org.apache.ibatis.session;

/**
* @author Eduardo Macarron
*/
public enum LocalCacheScope {
SESSION, //session 级别的缓存
STATEMENT //statement 级别的缓存
}

1)session 级别的缓存

在同一个 sqlSession 内,对同样的查询将不再查询数据库,直接从缓存中。

验证代码:

public static void main(String[] args) throws IOException {
InputStream inputStream = new ClassPathResource("mybatis.xml").getInputStream();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); System.out.println(mapper.get(1L));
System.out.println("-------------------");
System.out.println(mapper.get(1L));
}

输出:

日志输出可以看到,第一次查询通过数据库查询,第二次则没有,直接通过缓存读取。

:这种缓存策略有一个坑,在服务集群时就会出现问题。

假设现在有一个服务集群,有两个节点。

首先,两个节点都进行了同样的查询,两个节点都有自己的一级缓存,后续同样的查询,两个节点将不再查询数据库。

如果此时节点 1 执行了 update 语句,那么节点 1 的一级缓存会被刷新,而节点 2 的一级缓存不会改变。

2)statement 级别的缓存

避坑: 为了避免这个问题,可以将一级缓存的级别设为 statement 级别的,这样每次查询结束都会清掉一级缓存。MyBatis 源码如下:

在 MyBatis 的配置文件中,添加以下配置:

验证代码和上面的一样不变。

输出:

可以看到,即使是同样的查询,每次查询都是直接读取数据库了。

避坑完毕。

缓存是不可能不要缓存的,这个时候,就需要使用缓存中间件了,由缓存中间件管理缓存。

MyBatis 一级缓存避坑的更多相关文章

  1. Mybatis一级缓存和二级缓存总结

    1:mybatis一级缓存:级别是session级别的,如果是同一个线程,同一个session,同一个查询条件,则只会查询数据库一次 2:mybatis二级缓存:级别是sessionfactory级别 ...

  2. Mybatis一级缓存和二级缓存 Redis缓存

    一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对 ...

  3. MyBatis 一级缓存与二级缓存

    MyBatis一级缓存 MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空 1.执行session.clearCache(); 2.执行CUD操作 3. ...

  4. MyBatis一级缓存引起的无穷递归

    MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...

  5. mybatis一级缓存详解

    mybatis缓存分为一级缓存,二级缓存和自定义缓存.本文重点讲解一级缓存 一:前言 在介绍缓存之前,先了解下mybatis的几个核心概念: * SqlSession:代表和数据库的一次会话,向用户提 ...

  6. 0065 MyBatis一级缓存与二级缓存

    数据库中数据虽多,但访问频率却不同,有的数据1s内就会有多次访问,而有些数据几天都没人查询,这时候就可以将访问频率高的数据放到缓存中,就不用去数据库里取了,提高了效率还节约了数据库资源 MyBatis ...

  7. 关于mybatis 一级缓存引发的问题

    场景: 由于在一个方法中存在多个不同业务操作 private void insertOrUpdateField(CompanyReport entity) { //计算并数据 calcReportDa ...

  8. MyBatis一级缓存(转载)

    <深入理解mybatis原理> MyBatis的一级缓存实现详解 及使用注意事项 http://demo.netfoucs.com/luanlouis/article/details/41 ...

  9. MyBatis 一级缓存、二级缓存全详解(一)

    目录 MyBatis 一级缓存.二级缓存全详解(一) 什么是缓存 什么是MyBatis中的缓存 MyBatis 中的一级缓存 初探一级缓存 探究一级缓存是如何失效的 一级缓存原理探究 还有其他要补充的 ...

随机推荐

  1. **深入了解lambda

    之前已经了解过lambda了,但是在学习了闭包之后,我们有必要在探讨一下lambda(匿名函数). 匿名函数本质上就是一个函数,它所抽象出来的东西是一组运算. 它的使用场景就是:你在某处就真的只需要使 ...

  2. Spark中RDD的常用操作(Python)

    弹性分布式数据集(RDD) Spark是以RDD概念为中心运行的.RDD是一个容错的.可以被并行操作的元素集合.创建一个RDD有两个方法:在你的驱动程序中并行化一个已经存在的集合:从外部存储系统中引用 ...

  3. ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数

    有程序没关闭游标, --打开了哪些游标 select * from v$open_cursor 在open cursor之后一定要注意要close cursor(在store procedure里更应 ...

  4. Spark之 SparkSql、DataFrame、DataSet介绍

    SparkSql SparkSql是专门为spark设计的一个大数据仓库工具,就好比hive是专门为hadoop设计的一个大数据仓库工具一样. 特性: .易整合 可以将sql查询与spark应用程序进 ...

  5. 第一个MFC实例:计算圆周长和圆面积

    一.基于Microsoft MFC的编程方法 MFC是微软基础类库(Microsoft Foundation Class)的缩写.与API不同,MFC不是Windows操作系统的组成部分,而是微软公司 ...

  6. 53-C++ CH08 01

     http://lx.lanqiao.cn/problem.page?gpid=T407 算法训练 C++ CH08 01   时间限制:1.0s   内存限制:256.0MB      问题描述 已 ...

  7. ServiceStack.redis用法

    using System; using System.Collections.Generic; using ServiceStack.Redis; namespace SysBuild { class ...

  8. Django框架请求生命周期

    先看一张图吧! 1.请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask.Django) - 中间件,帮助我们对请求进行校 ...

  9. [GO]接口的转换

    package main import "fmt" type Humaner interface { //子集 SayHi() } type Personer interface ...

  10. 【转】JAVA 并发编程-多个线程之间共享数据

    原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...