mybatis一级缓存

mybatis的一级缓存是会话级缓存,只存在于当前会话,生命周期短。它依赖于Map存储查询结果,当sql、statement、session及RowBounds完全相同时,才会命中一级缓存。一级缓存的命中、访问、查询失败和失效情况各有特点,例如更新操作会导致一级缓存失效。在mybatis与spring整合时,由于动态代理导致的sqlSession变化会使一级缓存失效,解决方案是在同一事务中使用相同sqlSession。
摘要由CSDN通过智能技术生成

mybatis一级缓存

mybatis一级缓存:也叫做会话级缓存,生命周期仅存在于当前会话,不可以直接关关闭。但可以通过flushCache和localCacheScope对其做相应控制。

一级缓存源码

底层是map集合,其中的key是sql、statement等一共组成。value值就是查询的结果

public class PerpetualCache implements Cache {
   

  private final String id;

  private final Map<Object, Object> cache = new HashMap<>();
  }

交给BaseMapper实现一级缓存,一级缓存是默认开启的,同一线程当中的缓存,是单线程的

public abstract class BaseExecutor implements Executor {
   

  private static final Log log = LogFactory.getLog(BaseExecutor.class);

  protected Transaction transaction;
  protected Executor wrapper;

  protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
  protected PerpetualCache localCache;
  protected PerpetualCache localOutputParameterCache;
  protected Configuration configuration;

  protected int queryStack;
  private boolean closed;
  }

一级缓存的命中

1.sql和参数必须相同
2.必须是相同的statementID
3.sqlSession必须一样(会话级缓存)
4.RowBounds返回行范围必须相同(分页用的)

只有当以上情况完全相同,才会命中一级缓存。
在这里插入图片描述

一级缓存当中的访问

BaseExecutor -> query() 如果一级缓存中有,就访问一级缓存当中数据,就是key命中,如果没有命中一级缓存,就会调用queryFromDatabase(),接着调用doQuery()方法,查询数据库,填入缓存、
*注意 *:此时会使用创建的key创建一个缓存, CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);根据信息创建key,调用doQuery()之后会将key,以及一个占位符放到缓存中,localCache.putObject(key, EXECUTION_PLACEHOLDER);此处是为了懒加载使用,后面我会单独写。

@Override
  public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
   
    BoundSql boundSql = ms.getBoundSql(parameter);
    CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
    return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
  }

  @SuppressWarnings("unchecked")
  @Override
  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())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值