`
lifei114
  • 浏览: 26619 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

IBatis 的缓存机制

阅读更多

IBatis 的缓存机制

 

缓存机制,也是基于 Key-Value 的方式,确定了 Key 的来龙去脉能很好的认识缓存的生存周期。
从配置文件解析说起:

 

01  parser.addNodelet("/sqlMap/cacheModel", new Nodelet() {
02  public void process(Node node) throws Exception ...{
03  Properties attributes = NodeletUtils.parseAttributes(node, state.getGlobalProps());
04  String id = state.applyNamespace(attributes.getProperty("id"));
05  String type = attributes.getProperty("type");
06  String readOnlyAttr = attributes.getProperty("readOnly");
07  Boolean readOnly = readOnlyAttr == null || readOnlyAttr.length() <= 0 ? null : new Boolean("true".equals(readOnlyAttr));
08  String serializeAttr = attributes.getProperty("serialize");
09  Boolean serialize = serializeAttr == null || serializeAttr.length() <= 0 ? null : new Boolean("true".equals(serializeAttr));
10  type = state.getConfig().getTypeHandlerFactory().resolveAlias(type);
11  Class clazz = Resources.classForName(type);
12  if (readOnly == null) ...{
13  readOnly = Boolean.TRUE;
14  }

15  if (serialize == null) ...{
16  serialize = Boolean.FALSE;
17  }

18  CacheModelConfig cacheConfig = state.getConfig().newCacheModelConfig(id, (CacheController) Resources.instantiate(clazz), readOnly.booleanValue(), serialize.booleanValue());
19  state.setCacheConfig(cacheConfig);
20  }

21  });

 

上面红色的代码很关键,它是 Statement 中,对应的Cache 的Key 就是它。返回的对象:CacheModelConfig,对应的部分代码如下:

 

 

01 private ErrorContext errorContext;
02   private CacheModel cacheModel;
03
04     CacheModelConfig(SqlMapConfiguration config, String id, CacheController controller, boolean readOnly, boolean serialize) ...{
05       this.errorContext = config.getErrorContext();
06       this.cacheModel = new CacheModel();
07       SqlMapClientImpl client = config.getClient();
08       errorContext.setActivity("building a cache model");
09       cacheModel.setReadOnly(readOnly);
10  cacheModel.setSerialize(serialize);
11      errorContext.setObjectId(id + " cache model");
12      errorContext.setMoreInfo("Check the cache model type.");
13      cacheModel.setId(id);
14      cacheModel.setResource(errorContext.getResource());
15       try ...{
16         cacheModel.setCacheController(controller);
17        }
catch (Exception e) ...{
18      throw new RuntimeException("Error setting Cache Controller Class. Cause: " + e, e);
19  }

20  errorContext.setMoreInfo("Check the cache model configuration.");
21 if (client.getDelegate().isCacheModelsEnabled()) ...{
22  client.getDelegate().addCacheModel(cacheModel);
23  }

24  errorContext.setMoreInfo(null);
25  errorContext.setObjectId(null);
26  }

 

注意红色的代码,再来看看 CacheModel,如下:

 

 

1 public class CacheModel implements ExecuteListener

 

ExecuteListener 是一个监听器,它在 Update、insert,delete 操作执行后,触发些事件:源头如下:

 

01 com.ibatis.sqlmap.engine.mapping.statement.MappedStatement
02 public int executeUpdate(StatementScope statementScope, Transaction trans, Object parameterObject)
03 throws SQLException ...{
04 ErrorContext errorContext = statementScope.getErrorContext();
05 errorContext.setActivity("preparing the mapped statement for execution");
06 errorContext.setObjectId(this.getId());
07 errorContext.setResource(this.getResource());
08
09 statementScope.getSession().setCommitRequired(true);
10
11 try ...{
12 parameterObject = validateParameter(parameterObject);
13
14 Sql sql = getSql();
15
16 errorContext.setMoreInfo("Check the parameter map.");
17 ParameterMap parameterMap = sql.getParameterMap(statementScope, parameterObject);
18
19 errorContext.setMoreInfo("Check the result map.");
20 ResultMap resultMap = sql.getResultMap(statementScope, parameterObject);
21
22 statementScope.setResultMap(resultMap);
23 statementScope.setParameterMap(parameterMap);
24
25 int rows = 0;
26
27 errorContext.setMoreInfo("Check the parameter map.");
28 Object[] parameters = parameterMap.getParameterObjectValues(statementScope, parameterObject);
29
30 errorContext.setMoreInfo("Check the SQL statement.");
31 String sqlString = sql.getSql(statementScope, parameterObject);
32
33 errorContext.setActivity("executing mapped statement");
34 errorContext.setMoreInfo("Check the statement or the result map.");
35 rows = sqlExecuteUpdate(statementScope, trans.getConnection(), sqlString, parameters);
36
37 errorContext.setMoreInfo("Check the output parameters.");
38 if (parameterObject != null) ...{
39 postProcessParameterObject(statementScope, parameterObject, parameters);
40 }

41
42 errorContext.reset();
43 sql.cleanup(statementScope);
44 notifyListeners();
45 return rows;
46 }
catch (SQLException e) ...{
47 errorContext.setCause(e);
48 throw new NestedSQLException(errorContext.toString(), e.getSQLState(), e.getErrorCode(), e);
49 }
catch (Exception e) ...{
50 errorContext.setCause(e);
51 throw new NestedSQLException(errorContext.toString(), e);
52 }

53 }

54
55 public void notifyListeners() ...{
56 for (int i = 0, n = executeListeners.size(); i < n; i++) ...{
57 ((ExecuteListener) executeListeners.get(i)).onExecuteStatement(this);
58 }

59 }

 

再看 CacheModel 是如何处理的:

 

 

01 public void onExecuteStatement(MappedStatement statement) {
02 flush();
03 }
04
05 public void flush() ...{
06     synchronized (this) ...{
07 controller.flush(this);
08 lastFlush = System.currentTimeMillis();
09 if ( log.isDebugEnabled() ) ...{
10 log("flushed", false, null);
11 }

12 }

13 }

 

controller 是实现以下接口的类

    public interface CacheController

实现以下几种:

    FifoCacheController

    LruCacheController

    MemoryCacheController

    OSCacheController

再看看具体的实现,如MemoryCacheController的:

 

private Map cache = Collections.synchronizedMap(new HashMap());

1 public void flush(CacheModel cacheModel) {
2 cache.clear();
3 }

 

其它的几种实现,也基本大致如此,不在具体贴代码了。

从上面的代码分析可以看出 IBatis 的缓存的更新机制大概如下:

执行 update,insert,delete 等操作时,触发对应的事件,注册的事件响应此操作,根据XML配置的缓存,对其数据做清空操作,也就是这个缓存中的数据全部清空,而不是

清空某一个 Key对应的值,即如我更新了一个 id= 5 的数据,则这个缓存中的数据全部将清空。这样倒很简单也很彻底,由此带来的问题就很多了,如果你的 update 等相关的操作太频繁了,这里的缓存则失去意义,且加大了系统本身的开销。因此,我认为对于更新不是很频繁的数据可以用 IBatis 自身的缓存机制,如果是很频繁的数据就不要使用 IBatis 自身的缓存。举例说明:

 

01 <cacheModel id="product-cache" imlementation="LRU">
02 <flushInterval hours="24"/>
03 <flushOnExecute statement="insertProduct"/>
04 <flushOnExecute statement="updateProduct"/>
05 <flushOnExecute statement="deleteProduct"/>
06 <property name="size" value="1000" />
07 </cacheModel>
08 <statement id="getProductList" parameterClass="int" cacheModel="product-cache">
09 select * from PRODUCT where PRD_CAT_ID = #value#
10 </statement>

如果你配置了以上操作,如果做了  insert_product,updateProduct,deleteProduct 中的任何一个操作,都将清空缓存 product-cache 中的所有数据,也就是getProductList 方法将执行数据库操作,不能从缓存中获取数据。

 

最后一句,大家不要对 IBatis 的缓存抱太大的希望,虽然我们的系统中使用的是 IBatis。

 

结束,下次再说IBatis 的 SQL 的缓存机制。http://lifei114.iteye.com/blog/583178

2
1
分享到:
评论

相关推荐

    iBATIS缓存介绍

    ### iBATIS缓存介绍 #### 一、缓存知识介绍 ##### 1.1 缓存对象 理论上,Web分层设计的各个层都可以有缓存,Web中的任何对象都可以成为缓存的对象。例如: - **HTTP请求结果的缓存**:包括浏览器缓存、代理缓存...

    iBATIS缓存介绍[借鉴].pdf

    通过上述介绍,我们可以看到iBATIS缓存机制是其性能优化的关键组成部分,通过合理的配置和选择合适的缓存策略,可以显著提升系统的响应速度和整体性能。在实际开发中,理解并掌握这些概念和配置方法,对于优化iBATIS...

    iBATIS缓存

    iBATIS的缓存机制不仅限于简单的数据存储,还支持基于查询条件的缓存。通过设置`flushCache="true"`,可以在某些操作(如插入、更新或删除)后强制清空相应的一级或二级缓存,确保缓存中的数据与数据库保持同步。 ...

    解决IBatis缓存动态字段问题

    这种情况下,由于IBatis的缓存机制,可能导致字段找不到的问题。具体表现为:当第一次查询某个表时,IBatis会将查询结果中的字段名缓存起来;而在后续查询其他表时,如果这些表的字段与之前缓存的字段不一致,就会...

    iBATIS缓存的使用方法

    ### iBATIS缓存的使用方法 在数据库访问框架iBATIS中,缓存机制是一项重要的功能,它能够显著提高应用程序的性能。本文将详细介绍iBATIS中的缓存使用方法,包括缓存模型的配置、不同类型的缓存控制器以及如何在SQL...

    ibatis 缓存配置策略

    iBatis 提供了本地缓存机制,用于存储查询结果集,减少不必要的数据库访问。以下是对iBatis缓存配置策略的深入解析: 首先,iBatis 的 Cache 键(key)是由多个因素组成的,包括对象的hashCode、checksum、查询参数...

    Java ibatis缓存技术

    ### Java ibatis缓存技术详解 #### 一、ibatis缓存概述 ibatis是一款流行的持久层框架,它简化了Java应用程序与数据库之间的交互过程。ibatis提供了多种特性,其中包括缓存机制,这对于提高应用程序的性能至关重要...

    ibatis-缓存使用示例

    总之,iBATIS缓存是提升系统效率的关键技术之一,理解其工作机制并恰当运用,对于构建高效、稳定的应用至关重要。通过"ibatis-缓存使用示例"的学习,开发者能更好地掌握这一技巧,从而在实际项目中发挥出更大的价值...

    ibatis培训教程

    - **iBATIS缓存机制**: - 一级缓存: 自动启用,存储在会话级别,用于存储SQL执行的结果。 - 二级缓存: 需要手动启用,存储在映射文件级别,可以在多个会话之间共享数据。 - **缓存配置**: - 在`SqlMapConfig.xml`...

    Java_ibatis缓存技术

    本文将深入探讨Java_iBatis缓存技术,包括它的概念、类型、配置以及在实际应用中的注意事项。 首先,缓存是一种存储机制,用于临时存放频繁访问的数据,减少数据库的读取次数,从而提高系统响应速度。在iBatis中,...

    ibatis开发手册

    #### 四、ibatis缓存机制 - **MEMORY类型Cache与WeakReference**: - 内存级别的缓存,使用WeakReference可以避免内存泄漏的风险。 - **LRU型Cache**:Least Recently Used,最近最少使用的缓存策略,当缓存满时,...

    J2EE WEB缓存技术详解.doc

    **ibatis缓存机制** - ibatis(现MyBatis)框架也提供了缓存机制,包括一级缓存(本地缓存,类似于JCS的内存区域)和二级缓存(跨SQL会话的缓存,类似JCS的磁盘区域或远程区域)。这表明,缓存机制是提高数据访问...

    ibatis_数据缓存

    iBatis 数据缓存机制是提高数据库访问性能的重要手段,它允许将查询结果存储在内存中,以便后续相同查询能够快速获取数据,而无需每次都执行SQL查询。在深入理解iBatis的Cache概念之前,首先需要知道iBatis是一个轻...

    ibatis demo,ibatis例子,ibatis示例

    7. **缓存机制**:Ibatis内置了本地缓存和二级缓存,可以提高数据读取速度。本地缓存作用于单个SqlSession,而二级缓存则可以在多个SqlSession之间共享,但需要注意并发控制和数据一致性问题。 8. **插件支持**:...

    ibatis源码,ibatis源码 ibatis源码 ibatis源码

    十、缓存机制 iBatis提供了本地缓存和二级缓存,通过CachingExecutor实现。缓存策略可以在全局配置文件中配置,也可以在每个Mapper中单独设置。源码中`org.apache.ibatis.cache.Cache`接口定义了缓存的基本操作,而...

    ibatisDemo.zip

    5. **缓存机制**:Ibatis内置了本地缓存和二级缓存,能够提高数据读取速度,减少数据库压力。 接下来,我们来看看压缩包中的"ibatisDemo"可能包含的内容: - **CRUD示例**:这通常是一系列的Java类和XML配置文件,...

    ibatis开发指南 经典教材

    为了提高查询性能,ibatis内置了多种缓存机制,包括`MEMORY`类型缓存、`LRU`(Least Recently Used)型缓存、`FIFO`(First In First Out)型缓存和`OSCache`。其中,`MEMORY`类型缓存使用弱引用(WeakReference)来...

    ibatis api,ibatis文档,ibatis说明文档

    6. 缓存:Ibatis提供了本地缓存和二级缓存机制,有助于提高性能。 7. 执行性能:提供优化建议,如批处理、缓存使用等,以提升应用程序的运行效率。 总之,Ibatis是一个强大且灵活的Java持久层框架,其API、文档和...

Global site tag (gtag.js) - Google Analytics