读书人

ibatis的缓存中计算cachekey的进程

发布时间: 2013-04-05 10:24:33 作者: rapoo

ibatis的缓存中计算cachekey的过程

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

?

?

CachingStatementpublic 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

?

MappedStatementpublic 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。

?

BaseDataExchangepublic 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的一部分。

读书人网 >开源软件

热点推荐