ibatis的缓存中计算cachekey的过程

CachingStatement在执行查询的时候,会先从CacheModel中获取结果。如果结果为空,则执行查询并将结果保存在CacheModel中。在读写CacheModel的过程中,都需要获得CacheKey对象,以CacheKey作为缓存的key。下面是获得CacheKey的过程:

CachingStatement
public CacheKey getCacheKey(StatementScope statementScope, Object parameterObject) {
//调用了MappedStatement的getCacheKey
    CacheKey key = statement.getCacheKey(statementScope, parameterObject);
//如果cacheModel不是只读的而且不是可序列化的,则将当前的session信息作为CacheKey的一部分 
   if (!cacheModel.isReadOnly() && !cacheModel.isSerialize()) {
      key.update(statementScope.getSession());
    }
    return key;
  }

MappedStatement中获得CacheKey的时候使用了几个因素:sql语句的id,baseCacheKey和sql语句本身

sdf

MappedStatement
public CacheKey getCacheKey(StatementScope statementScope, Object parameterObject) {
    Sql sql = statementScope.getSql();
    ParameterMap pmap = sql.getParameterMap(statementScope, parameterObject);
//调用ParameterMap的方法
    CacheKey cacheKey = pmap.getCacheKey(statementScope, parameterObject);
    cacheKey.update(id);
    cacheKey.update(baseCacheKey);
    cacheKey.update(sql.getSql(statementScope, parameterObject)); //Fixes bug 953001
    return cacheKey;
  }
ParameterMap
 public CacheKey getCacheKey(StatementScope statementScope, Object parameterObject) {
    return dataExchange.getCacheKey(statementScope, this, parameterObject);
  }

BaseDataExchange中 调用了PrimitiveDataExchange的getData,用getData得到的数组来更新key,也就是使用这次sql调用的参数值来更新key。

BaseDataExchange
public CacheKey getCacheKey(StatementScope statementScope, ParameterMap parameterMap, Object parameterObject) {
    CacheKey key = new CacheKey();
    Object[] data = getData(statementScope, parameterMap, parameterObject);
    for (int i = 0; i < data.length; i++) {
      if (data[i] != null) {
        key.update(data[i]);
      }
    }
    return key;
  }

 PrimitiveDataExchange从ParameterMap中获得参数的个数,创建对象数组data,将parameterObject付给数组的每个元素。

PrimitiveDataExchange
 public Object[] getData(StatementScope statementScope, ParameterMap parameterMap, Object parameterObject) {
    ParameterMapping[] mappings = parameterMap.getParameterMappings();
    Object[] data = new Object[mappings.length];
    for (int i = 0; i < mappings.length; i++) {
      data[i] = parameterObject;
    }
    return data;
  }

CacheKey的update方法,增加参数计数值,修改checksum和baseHashCode,使用参数的hashcode值和caseHashCode来更新当前cachekey的hashcode

CacheKey
  public CacheKey update(Object object) {
    int baseHashCode = object.hashCode();

    count++;
    checksum += baseHashCode;
    baseHashCode *= count;

    hashcode = multiplier * hashcode + baseHashCode;

    paramList.add(object);

    return this;
  }

综上所述,计算cachekey的因素包括baseHashCode,sql语句的id,sql语句本身和每次调用传入的sql参数值。如果cacheModel不是只读的而且不是可序列化的,则将当前的session信息也作为CacheKey的一部分。

猜你喜欢

转载自javavsnet.iteye.com/blog/1841441