您的位置:首页 > 其它

Ibatis 缓存

2013-08-23 23:11 267 查看
相关类



ibatis配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="User">
<cacheModel id="user_cache" type="MEMORY">
<flushInterval hours="24"/>
<flushOnExecute statement="getUser"/>
<property name="reference-type" value="WEAK" />
</cacheModel>
<typeAlias alias="user" type="com.model.User"/>
<select id="getUser" parameterClass="java.lang.String" resultClass="user"
cacheModel="user_cache"> <![CDATA[
select name as name,id
from user
where name = #name#]]> </select>
</sqlMap>


当配置文件配置了使用缓存后,实现执行时会使用CachingStatement来执行sql,相关代码

public Object executeQueryForObject(StatementScope statementScope, Transaction trans, Object parameterObject, Object resultObject)
throws SQLException {
CacheKey cacheKey = getCacheKey(statementScope, parameterObject);
cacheKey.update("executeQueryForObject");
Object object = cacheModel.getObject(cacheKey);//获取缓存
if (object == CacheModel.NULL_OBJECT){
//    This was cached, but null
object = null;
}else if (object == null) {
object = statement.executeQueryForObject(statementScope, trans, parameterObject, resultObject);
cacheModel.putObject(cacheKey, object);
}
return object;
}


key的生成方法

sql的id、参数、sql语句,还有一些固定参数生成hashcode,放入cacheKey,

所以同一sql第二次执行时,缓存如果还有,则直接返回结果,不再执行sql

public CacheKey getCacheKey(StatementScope statementScope, Object parameterObject) {
Sql sql = statementScope.getSql();
ParameterMap pmap = sql.getParameterMap(statementScope, parameterObject);
CacheKey cacheKey = pmap.getCacheKey(statementScope, parameterObject);
cacheKey.update(id);//sql的id
cacheKey.update(baseCacheKey);

//select name as name,id   from user   where name = ?
cacheKey.update(sql.getSql(statementScope, parameterObject)); //Fixes bug 953001
return cacheKey;
}


User user = (User) sqlMapClient.queryForObject("getUser", "test");
User user2 = (User) sqlMapClient.queryForObject("getUser", "test");

执行结果:

第一次执行

hashcode=-1700962362
CacheModel - Cache 'User.user_cache': cache miss
SimpleDataSource - Created connection 21185076.
Connection - {conn-100000} Connection
Connection - {conn-100000} Preparing Statement: select name as name,id from user where name = ?
PreparedStatement - {pstm-100001} Executing Statement: select name as name,id from user where name = ?
PreparedStatement - {pstm-100001} Parameters: [test]
PreparedStatement - {pstm-100001} Types: [java.lang.String]
ResultSet - {rset-100002} ResultSet
ResultSet - {rset-100002} Header: [name, id]
ResultSet - {rset-100002} Result: [test, 1]
CacheModel - Cache 'User.user_cache': flushed
CacheModel - Cache 'User.user_cache': stored object 'com.model.User@15212bc'
SimpleDataSource - Returned connection 21185076 to pool.

每二次执行
CacheModel - Cache 'User.user_cache': retrieved object 'com.model.User@15212bc'
hashcode=-1700962362

问题:当数据库数据已更新时,是否还是直接返回缓存,是否要在缓存过期后才会重新查询?

User user = (User) sqlMapClient.queryForObject("getUser", "test");
System.out.println("id=" + user.getId());

Thread.sleep(20000);

User user2 = (User) sqlMapClient.queryForObject("getUser", "test");
System.out.println("id=" + user.getId());


用以上代码测试,执行第一条后,立即手工执行update,改变数据 库数据,第二次的结果仍是缓存结果

所以缓存会等到过期后才更新,不会自动去更新
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: