相关类
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,改变数据 库数据,第二次的结果仍是缓存结果
所以缓存会等到过期后才更新,不会自动去更新
此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/68649.html