精华内容
下载资源
问答
  • mybatis二级缓存弊端

    千次阅读 2019-07-11 10:42:31
    如果mapper中sql查询是多表关联查询,在开启二级缓存的情况下,第一次查询会在map中存放缓存,此时是application级下的map,第二次查询时候如果关联的表有修改,此时缓存数据是不变的,而查询依旧会命中,此时查询的...

    简单了解了下,个人观点

    如果mapper中sql查询是多表关联查询,在开启二级缓存的情况下,第一次查询会在map中存放缓存,此时是application级下的map,第二次查询时候如果关联的表有修改,此时缓存数据是不变的,而查询依旧会命中,此时查询的数据就是脏数据。

    展开全文
  • mybatis二级缓存缺陷

    千次阅读 2019-01-24 12:22:38
    或者这样理解,二级缓存是保存在Mapper对象中的,现在有一张user表,两个Mapper文件,AMapper.xml和BMapper.xml,B修改了user表中的内容,A是感知不到的,那么再从A里查询如果用到了缓存,就是旧的数据。

    转载:https://www.cnblogs.com/xrq730/p/6991655.html
    在这里插入图片描述
    或者这样理解,二级缓存是保存在Mapper对象中的,现在有一张user表,两个Mapper文件,AMapper.xml和BMapper.xml,B修改了user表中的内容,A是感知不到的,那么再从A里查询如果用到了缓存,就是旧的数据。

    展开全文
  • mybatis缓存分为一级缓存与二级缓存。 一级缓存是自带的,使用时不用配置。 一级缓存作用域: 同一个sqlSession中:当同一个sqlSession在同一条sql且相同查询条件下,且中间无commit操作时,mybatis不会...

    缓存:首先持久层框架缓存不会优化sql来节省整个业务流程的时间,而是减少查询次数来缩短业务的执行时间。

    缓存中存放数据:经常使用且对实时性要求并不高的内容。

    mybatis缓存分为一级缓存与二级缓存。

    一级缓存是自带的,使用时不用配置。

    一级缓存作用域: 同一个sqlSession中:当同一个sqlSession在同一条sql且相同查询条件下,且中间无commit操作时,mybatis不会再次发起sql查询。

     

     一级缓存测试:

    1、两次查询再无commit()语句执行的时候(避免脏读),

    sqlSession缓存了查询结果,再次查询时直接输出查询结果。

    2 包含commit()的操作会刷新缓存区

    commit后,将持续发送数据库sql请求。

    二级缓存测试:

    二级缓存:作用范围当前namespace下,可以跨sqlSession的。即相同namespace的查询且条件相同的sql,不同sqlSession发起请求不会对数据库发送sql。当任一sqlSession执行commit()(insert,update,delete)时,会清空整个namespace的缓存。

    首先设置mybatis打开二级缓存。

    1sqlMapConfig.xml中

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

    2xxxMapper.xml中配置<cache>标签。(mybatis有默认的cache接口实现类:org.apache.ibatis.cache.impl.PerpetualCache);

    此图可看出,二级缓存和一级缓存都存在的情况下,先查询二级缓存。

    commit();操作同一级缓存,会清空二级缓存。

    ehcache结合mybatis:

    因为mybatis的缓存是本地的(未测试)。服务器集群中sqlSession不会共享问题(未测试)。

    所以结合ehcache分布式缓存来处理。

    设置方法:

    1引入mybatis-ehcache注意和mybatis版本一致性。

    <dependency>
                <groupId>org.mybatis.caches</groupId>
                <artifactId>mybatis-ehcache</artifactId>
                <version>1.1.0</version>
            </dependency>
            <!-- ehcache核心jar包 -->
            <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache-core</artifactId>
                <version>2.6.11</version>
            </dependency>
            <!-- mysql -->

    2设置xxxMapper.xml中<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

    3classpath下chcache.xml。

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        updateCheck="false" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

        <diskStore path="D:\ehcache" />

        <defaultCache maxElementsInMemory="10000" eternal="false"
            timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU">
            <persistence strategy="localTempSwap" />
        </defaultCache>
    </ehcache>

    测试方法同二级缓存测试。

     

    二级缓存弊端:

    1、因为是相同namespace作用于,会导致多表查询的情况下

    user - order 表, userOrderMapper.xml中的多表查询,当userMapper.xml中执行更新操作。userOrderMapper的关联查询是不会更新操作的。

    2、因为二级缓存是相同namespace级别的。例如查询商品信息的需求,当执行商品的信息更新时,该namespace下的所有查询缓存都会被清理掉!!。

    展开全文
  • mybatis二级缓存深入理解 在我们日常项目中使用,我们常常不会选择使用MyBatis的二级缓存,因为当你不熟悉二级缓存的时候。由于使用不当很容易造成脏读,下面我们就来看看二级缓存的槽点和亮点。 首先我们得知道二...

    mybatis二级缓存深入理解

    在我们日常项目中使用,我们常常不会选择使用MyBatis的二级缓存,因为当你不熟悉二级缓存的时候。由于使用不当很容易造成脏读,下面我们就来看看二级缓存的槽点和亮点。

    首先我们得知道二级缓存需要做什么

    二级缓存(应用级缓存、跨线程)不同于一级缓存(会话级缓存、线程不安全),所以他的命中率比一级缓存命中率更高

    其中二级缓存有几个比较核心的知识点:

    1、存储方式:

    ​ 1)、内存:这是我们最常用的方式,简单快捷;弊端就是不能持久化,并且容量有限。

    ​ 2)、硬盘:虽然可以持久化,容量也大,但是最大的弊端就是,访问速度慢!一般都不会用这种方式来做缓存。

    ​ 3)、第三方集成(redis):目前最为流行的方式,容量相对大,速度快且可持久化。并且Redis还能支持分布式系统

    2、淘汰策略:

    ​ 1)、FIFO 先进先出,底层使用队列来实现

    ​ 2)、LRU 最近最少使用 底层使用LinkedHashMap实现

    ​ 3)、WeakReference:弱应用,将缓存的对象进行弱应用包装。当JVM进行GC的时候,不论当前的内存空间是否够 用,此对象都会被清除。

    ​ 4)、SoftRefrence:软引用,基本原理与弱应用类似,不同在于当GC的时候,当内存空间不足的时候,此缓存对象就会 被回收。

    3、过期清理:清理存放数据过久的数据

    4、线程安全:保证缓存可以被多个线程同时使用

    6、序列化:关于序列化,由于二级缓存是应用级缓存,可以跨线线程使用。当不同线程获取到同一个对象时,做不同操作时,就会产生不同的结果相互影响。获取到的对象进行反序列化,获得的对象ID不同,但是对象的值相同,这样不同的操作就不会相互干扰。

    我们在查看源码时,必须首先要了解的设计模式。整个MyBatis 最亮点的设计,但是功能却使用的比较少;

    ​ 最主要的原因还是。在使用二级缓存的时候,需要使用或者@CacheNameSpace声明缓存空间。这极高的提高了灵活性,同时带来了公用缓存空间的弊端。在日益复杂的业务逻辑和分表的今天,在多表操作已经是非常常见的事!所以缓存空间就变得异常复杂不可控。脏数据读取就非常容易出现。

    使用到的设计模式:装饰器+责任链模式

    注意:这里的BlockingCache需要通过配置属性(@CacheNamespace(blocking = true))打开,默认是关闭的。

    通过源码debug,可以看出装饰器的链路。
    缓存的策略设置 通过@CacheNamespace注解,
    package org.apache.ibatis.annotations;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.apache.ibatis.cache.decorators.LruCache;
    import org.apache.ibatis.cache.impl.PerpetualCache;
    
    /**
     * @author Clinton Begin
     * @author Kazuki Shimizu
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface CacheNamespace {
      // 指定缓存的储存实现类,默认PerpetualCache是通过HashMap实现储存
      Class<? extends org.apache.ibatis.cache.Cache> implementation() default PerpetualCache.class;
    	
      // 淘汰策略 默认Lru
      Class<? extends org.apache.ibatis.cache.Cache> eviction() default LruCache.class;
    
      // 缓存的有效期 默认0 不过期
      long flushInterval() default 0;
    
      int size() default 1024;
    	
      // 是否进行序列化或者反序列化
      boolean readWrite() default true;
    
      // 是否防止缓存穿透
      boolean blocking() default false;
    
      /**
       * Property values for a implementation object.
       * @since 3.4.2
       */
      Property[] properties() default {};
    
    }
    
    

    MyBatis 查询之缓存访问流程

    在这里插入图片描述

    关于二级缓存的命中条件

    会话提交、SQL语句以及参数相同、相同的statementID、RowBounds相同。

    ​ 关于会话提交,跟接下来的缓存结构有关。这里在使用方面的考虑,先放张图

    关于二级缓存的结构

    我们先来看看缓存执行器的属性

    public class CachingExecutor implements Executor {
    	// 装饰器模式,指向下一个执行器
      private final Executor delegate;
      // 事务缓存管理器,
      private final TransactionalCacheManager tcm = new TransactionalCacheManager();
    }
    
    public class TransactionalCacheManager {
    
      private final Map<Cache, TransactionalCache> transactionalCaches = new HashMap<>();
    
      public void clear(Cache cache) {
        getTransactionalCache(cache).clear();
      }
    
      public Object getObject(Cache cache, CacheKey key) {
        return getTransactionalCache(cache).getObject(key);
      }
    
      public void putObject(Cache cache, CacheKey key, Object value) {
        getTransactionalCache(cache).putObject(key, value);
      }
    
      public void commit() {
        for (TransactionalCache txCache : transactionalCaches.values()) {
          txCache.commit();
        }
      }
    
      public void rollback() {
        for (TransactionalCache txCache : transactionalCaches.values()) {
          txCache.rollback();
        }
      }
    
      private TransactionalCache getTransactionalCache(Cache cache) {
        return transactionalCaches.computeIfAbsent(cache, TransactionalCache::new);
      }
    
    }
    

    通过源码我们可以看出源码,起决定作用的属性是TransactionalCacheManager,其中他提供了最基本的PUT缓存、GET缓存、clear缓存、commit等等操作。

    当不同的会话访问时,这个事务缓存管理器就发挥巨大的作用。这也是跨会话缓存的铁证

    下图就很好的体现了这个结构

    关于二级缓存执行流程

    CachingExecutor通过装饰器模式,加载在Executor的执行链中。

    查询操作query:

    ​ 当会话调用query() 时,会基于查询语句、参数等数据组成缓存Key,然后尝试从二级缓存中读取数据(实时获取)。读到就直接返回,没有就调用被装饰的Executor去查询数据库,然后在填充至对应的暂存区。

    更新操作update:(如果在查询中配置了flushCache=true,此时更新操作也会是这样)

    ​ 当执行update操作时,同样会基于查询的语句和参数组成缓存key,然后在执行update之前清空缓存。这里清空只针对暂存区,同时记录清空的标记,以便当会话提交之时,依据该标记去清空二级缓存空间。

    commit操作:

    ​ 当会话执行commit操作后,会话会将暂存区的变更提交到二级缓存中。

    下面是整个执行的流程

    在这里插入图片描述

    展开全文
  • mybatis和hibernate一样都是优秀的orm框架,但是两者的定位不同,所以有所差异,这里我们就从缓存的角度来介绍一下mybatis: 大家都知道使用mybatis就要先获取sqlsessionfactory,继而使用sqlsession来和数据库交互,...
  • 最近项目需要研究... mybatis中默认自带的二级缓存实现(PerpetualCache)是无法做到分布式的。 Java提供了一个开源的分布式缓存EhCache。它是一个纯Java的开源分布式缓存(进程内缓存),具有快速、精干等特...
  • MyBatis缓存策略之二级缓存

    万次阅读 2017-09-15 15:35:15
     前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper通常情况下有不同的namespace,就都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的。为了更加清楚的描述二级...
  • 级缓存级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个...
  • MyBatis学习13】MyBatis中的二级缓存

    万次阅读 多人点赞 2016-06-16 07:26:19
    1. 二级缓存的原理 前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的。为了更加清楚的描述二级缓存,先来看一...
  • 上一篇也提到了mybatis二级缓存弊端,二级缓存作用域有一点是针对xml文件。 假设我们在A.xml缓存了结果集,在B.xml修改了同一条DB数据,则无法影响A.xml中的缓存数据,可能导致缓存与DB数据不一致的问题。 所以...
  • mybaits的二级缓存是mapper范围级别,要在具体的mapper.xml中开启二级缓存。 在核心配置文件 中加入: <setting name="cacheEnabled"value=“true”/> <settings> <!-- 开启二级缓存 默认值为true ...
  • Mybatis二级缓存问题

    万次阅读 2017-06-28 21:09:53
    一、一级缓存、二级缓存的定义及区别 我们知道mybatis的对JDBC 的一个轻量级的封装,在运行速度方面优于hibernate。 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象...
  • 文章目录一、前言二、一级缓存三、二级缓存3.1、开启二级缓存:四、测试一下五、总结: 一、前言 先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,...
  • 一、mybatis缓存基本介绍 1、缓存:将相同查询条件的sql...2、mybatis的查询缓存又分为一级缓存和二级缓存,一级缓存的作用范围为同一个sqlsession,而二级缓存的作用范围为同一个namespace和mapper。 二、一级缓...
  • MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。本文将全面分析MyBatis的... Mybatis二级缓存设计分析 1. Mybatis缓存机制整体设计 如上图所示,当开启一个会话时...
  • mybatis开启二级缓存

    万次阅读 2018-06-01 23:15:10
    1.修改配置文件mybatis-config.xml加入&lt;setting name="cacheEnabled"value="true"/&gt;,全局配置参数,需要时再设置cacheEnabled 介绍描述 : ...在mapper.xml中开启二缓存,ma...
  •  前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的。为了更加清楚的描述二级缓存,先来看一个示意图:    ...
  • Mybatis二级缓存

    2018-11-26 09:15:43
     前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper通常情况下有不同的namespace,就都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的。为了更加清楚的描述二级...
  • MyBatis中的二级缓存

    2018-09-01 13:48:08
     前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的。为了更加清楚的描述二级缓存,先来看一个示意图:  从图...
  • mybatis源码设计非常优秀,然后阅读源码又必须跨域一道门槛:缓存,虽然mybatis缓存已经不再适用现在的技术框架,但是仍有很多需要注意的地方。
  • Mybatis中一级缓存和二级缓存的区别

    千次阅读 2019-09-18 21:52:48
    mybatis默认是一级缓存级缓存指的就是Session缓存,也就是在同一个SqlSession中,不同的sqlSession中的缓存是互相不能读取的。 第一次在database中查询会保存在缓存中,第次或者n次都是在缓存中获取 优点:...
  • mybatis二级缓存

    2019-04-03 20:03:34
    1.修改配置文件mybatis-config.xml加入<settingname=...2.在mapper.xml中开启二缓存,mapper.xml下的sql执行完成会存储到它的缓存区,如: 开启缓存后,第一次查询会执行sql,第次及以后的查询都会...
  • 级缓存: 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个...
  • Mybatis 二级缓存

    2020-06-20 17:07:14
    这里写目录标题一级目录二级目录三级目录 一级目录 二级目录 三级目录
  • MyBatis中的一级缓存和二级缓存介绍

    千次阅读 多人点赞 2017-06-13 20:07:22
    先说缓存,合理使用缓存是优化...一级缓存级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也
  • 参考... ... Mybatis首先去缓存中查询结果集,如果没有则查询数据库,如果有则从缓存取出返回结果集就不走数据库。Mybatis内部存储缓存使用一个HashMap,key为hashCod...
  • mybatis-spring之一级缓存失效问题

    千次阅读 2019-01-25 16:10:19
    spring结合mybatis后mybaits一级缓存失效分为两种情况: 如果没有开启事务,每一次sql都是用的新的SqlSession,这时mybatis的一级缓存是失效的。 如果有事务,同一个事务中相同的查询使用的相同的SqlSessioon,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,739
精华内容 695
关键字:

mybatis二级缓存的弊端