mybatis一级缓存

在这里插入图片描述
这里使用了门面模式,实际的执行的Executor,门面就是SqlSession。
mybatis默认开启了一级缓存,默认的缓存级别是SESSION。
缓存失效的条件:

1、使用useCache,那这个语句不使用缓存

       useCache="false" 

2、使用flushCache,如果执行这个语句,所有缓存失效

 flushCache="false"

3、全局设置localCacheScope,这个原理是每次执行操作后,都会判断是否是SESSION,如果不是清除所有缓存

  <setting name="localCacheScope" value="STATEMENT"/>

4、执行增删改操作,以及提交,回滚操作
>这里可以谈一下原因,对于一个事务来说,select查询结果集的变化有增删改后,提交后,以及回滚,这必然导致查询数据的变化,而mybatis也对应这种变化

一级缓存的实现
在这里插入图片描述
责任链模式,单一职责

在这里插入图片描述

在这里插入图片描述
HashMap实现,所以一级缓存不是线程安全的

获取数据

list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;

直接使用hashmap,key就是cachekey,

  @Override
  public Object getObject(Object key) {
    return cache.get(key);
  }

hashmap key的生成

//CachingExecutor中查询的实现
  @Override
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    //生成key
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }
//BaseExecutor
@Override
  public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
   
    CacheKey cacheKey = new CacheKey();
    //id  
    cacheKey.update(ms.getId());
    //这里rowBound可以实现分页,不是sql语句的limit
    //可读取的开始位置
    cacheKey.update(rowBounds.getOffset());
    //可读取的结束位置
    cacheKey.update(rowBounds.getLimit());
    //语句
    cacheKey.update(boundSql.getSql());
    //语句参数
    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    
    TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
    // mimic DefaultParameterHandler logic
    for (ParameterMapping parameterMapping : parameterMappings) {
      if (parameterMapping.getMode() != ParameterMode.OUT) {
        Object value;
        String propertyName = parameterMapping.getProperty();
        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 = configuration.newMetaObject(parameterObject);
          value = metaObject.getValue(propertyName);
        }
        cacheKey.update(value);
      }
    }
    if (configuration.getEnvironment() != null) {
      // issue #176
      cacheKey.update(configuration.getEnvironment().getId());
    }
    return cacheKey;
  }
ParameterMapping{property='id', mode=IN, javaType=class java.lang.Integer, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}

CacheKey重写了equals,为了hashmap的判断

  @Override
  public boolean equals(Object object) {
    if (this == object) {
      return true;
    }
    if (!(object instanceof CacheKey)) {
      return false;
    }

    final CacheKey cacheKey = (CacheKey) object;

    if (hashcode != cacheKey.hashcode) {
      return false;
    }
    if (checksum != cacheKey.checksum) {
      return false;
    }
    if (count != cacheKey.count) {
      return false;
    }
   //比较
    for (int i = 0; i < updateList.size(); i++) {
      Object thisObject = updateList.get(i);
      Object thatObject = cacheKey.updateList.get(i);
      if (!ArrayUtil.equals(thisObject, thatObject)) {
        return false;
      }
    }
    return true;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值