ibatis的缓存机制

我现在遇到了一个问题
在sqlMap-config.xml里面配置的文件是

<![CDATA[
select $str$ from student
]]>

对应的方法是/**
* 获取数据库中字段内容的查询
* */
public List> getElement(String seq_str){
List> result = new ArrayList>();
result = baseDao.selectObjects("getElment", seq_str);
return result;
}
第一次我传进去的参数$str$是“id,name”则result得到的元素顺序是:“123,李四”第二次我传进去的参数$str$是“name,id”则result得到的元素顺序是"123,李四"也就是第二结果和第一次结果的顺序相同,我认为是ibatis自带的缓存的问题,所以会自动保留第一次结果的顺序。请大侠给出高解,在此非常感谢。

你可以试试这个解决办法,

resultClass="java.util.HashMap"

改成

resultClass="java.util.LinkedHashMap"

应该能达到你想要的效果。

[color=gray]我只是不理解这个需求,哈。[/color]

iBatis好久没有用过了。试试看猜的对不对,哈。

[quote]resultClass="java.util.HashMap"[/quote]
你设置的结果是HashMap,所以每次返回值应该都是

result =[{id=123, name=李四}, {id=456, name=张三}, ...]

类似这样的,无论你传进去是“id,name”,“name,id”都是一样的。

简单的说,就是HashMap里面的元素顺序和你定义的Key的顺序无关。(和Key值的HasdCode值来着?记不清了。)

看了一下mybatis3.0.6的源码,你的猜测是不对的。
BaseExecutor的query()源码如下:
[code="java"] public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
if (closed) throw new ExecutorException("Executor was closed.");

// Flush the internal cache is force is true
if (ms.isFlushCacheRequired()) {
    clearLocalCache();
}
List list;
try {
  queryStack++;
  CacheKey key = createCacheKey(ms, parameter, rowBounds); //创建缓存key
  list = resultHandler == null ? (List) localCache.getObject(key) : null; //默认首先从缓存读取数据
  if (list != null) {
    handleLocallyCachedOutputParameters(ms, key, parameter);
  } else {
    list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key); // 该方法中会将数据写入缓存
  }
} finally {
  queryStack--;
}
if (queryStack == 0) {
  for (DeferredLoad deferredLoad : deferredLoads) {
    deferredLoad.load();
  }
}
return list;

}[/code]
可以看到,如果传入的参数是$str$,它会做简单参数替换,由于两次的sql语句不相同,两次生成的CacheKey也是不相同的,缓存不生效。如果传入的参数是#{str},那么sql语句相同(都是使用?替换),所以缓存生效,可以解释上面的情况。
所以,如果按照你的描述,应该不是缓存的原因,具体原因我后面再debug一下源码。

remapResults="true" 这个属性改为false试试