Mybatis(五)一二级缓存

一级缓存

直接进执行器 BaseExecutor query方法

因为最终还是会进执行器 查询方法

public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds
rowBounds, ResultHandler resultHandler) throws SQLException {
    BoundSql boundSql = ms.getBoundSql(parameter);
    //组装一级缓存key值
    CacheKey key = this.createCacheKey(ms, parameter, rowBounds, boundSql);
    return this.query(ms, parameter, rowBounds, resultHandler, key, boundSql);
}

cachkey

根据statementId+分页页码+每页数量+sql语句 来构建key
 public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
    if (this.closed) {
        throw new ExecutorException("Executor was closed.");
    } else {
        CacheKey cacheKey = new CacheKey();
        cacheKey.update(ms.getId()); //statementId
        cacheKey.update(rowBounds.getOffset()); //分页页码
        cacheKey.update(rowBounds.getLimit());  //每页数量
        cacheKey.update(boundSql.getSql());     //sql语句
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
        Iterator var8 = parameterMappings.iterator();

        while(var8.hasNext()) {
            ParameterMapping parameterMapping = (ParameterMapping)var8.next();
            if (parameterMapping.getMode() != ParameterMode.OUT) {
                String propertyName = parameterMapping.getProperty();
                Object value;
                if (boundSql.hasAdditionalParameter(propertyName)) {
                    value = boundSql.getAdditionalParameter(propertyName);
                } else if (parameterObject == null) {
                    value = null;
                } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                    value = parameterObject;
                } else {
                    MetaObject metaObject = this.configuration.newMetaObject(parameterObject);
                    value = metaObject.getValue(propertyName);
                }

                cacheKey.update(value);
            }
        }

        if (this.configuration.getEnvironment() != null) {
            cacheKey.update(this.configuration.getEnvironment().getId());
        }

        return cacheKey;
    }
}

query

   public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
    if (this.closed) {
        throw new ExecutorException("Executor was closed.");
    } else {
        if (this.queryStack == 0 && ms.isFlushCacheRequired()) {
            this.clearLocalCache();
        }

        List list;
        try {
            ++this.queryStack;
            //去命中一级缓存
            list = resultHandler == null ?
            (List)this.localCache.getObject(key) : null;
            if (list != null) {
                this.handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
            } else {
            //不存在走数据库
                list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
            }
        } finally {
            --this.queryStack;
        }

        if (this.queryStack == 0) {
            Iterator var8 = this.deferredLoads.iterator();

            while(var8.hasNext()) {
                BaseExecutor.DeferredLoad deferredLoad = (BaseExecutor.DeferredLoad)var8.next();
                deferredLoad.load();
            }

            this.deferredLoads.clear();
            if (this.configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
                this.clearLocalCache();
            }
        }

        return list;
    }
}

二级缓存

直接进 CachingExecutor.query

开启2级缓存 执行器是CachingExecutor

  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
        BoundSql boundSql = ms.getBoundSql(parameterObject);
        CacheKey key = this.createCacheKey(ms, parameterObject, rowBounds, boundSql);
        return this.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
    }
    
      public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    Cache cache = ms.getCache();
    if (cache != null) {
        this.flushCacheIfRequired(ms);
        if (ms.isUseCache() && resultHandler == null) {
            this.ensureNoOutParams(ms, boundSql);
            //获取2级缓存
            List<E> list = (List)this.tcm.getObject(cache, key);
            if (list == null) {
                //走数据库
                list = this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                //设置预备的2级缓存 并没有设置进2级缓存
                this.tcm.putObject(cache, key, list);
            }

            return list;
        }
    }

    return this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}

TransactionalCacheManager 2级缓存管理

  只是把数据存入map中
   this.tcm.putObject(cache, key, list);
   
   private final Map<Cache, TransactionalCache> transactionalCaches = new HashMap();

只有当commit才会把数据刷入到缓存中

public void commit() {
Iterator var1 = this.transactionalCaches.values().iterator();

    while(var1.hasNext()) {
        TransactionalCache txCache = (TransactionalCache)var1.next();
        txCache.commit();
    }

}
public void commit() {
    if (this.clearOnCommit) {
        this.delegate.clear();
    }

    this.flushPendingEntries();
    this.reset();
}

private void flushPendingEntries() {
    Iterator var1 = this.entriesToAddOnCommit.entrySet().iterator();

    while(var1.hasNext()) {
        Entry<Object, Object> entry = (Entry)var1.next();
        this.delegate.putObject(entry.getKey(), entry.getValue());
    }

    var1 = this.entriesMissedInCache.iterator();

    while(var1.hasNext()) {
        Object entry = var1.next();
        if (!this.entriesToAddOnCommit.containsKey(entry)) {
            this.delegate.putObject(entry, (Object)null);
        }
    }

}

总结

2级缓存》1级缓存》数据库查询
2级缓存需要提交才会生效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值