原文地址:http://lifei114.javaeye.com/admin/blogs/581795
缓存机制,也是基于 Key-Value 的方式,确定了 Key 的来龙去脉能很好的认识缓存的生存周期。
从配置文件解析说起:
0 2 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 CacheModelConfigcacheConfig = state.getConfig().newCacheModelConfig(id,(CacheController) Resources.instantiate(clazz),readOnly.booleanValue(), serialize.booleanValue());
19 state.setCacheConfig(cacheConfig);
20 }
21 });
上面红色的代码很关键,它是 Statement 中,对应的Cache 的Key 就是它。返回的对象:CacheModelConfig,对应的部分代码如下:
0 2 private CacheModel cacheModel;
0 3
0 4 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 thrownew 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,如下:
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
ExecuteListener 是一个监听器,它在 Update、insert,delete 操作执行后,触发些事件:源头如下:
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
0 2
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
0 3
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
04
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
05
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
06
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
07
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
08
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
09
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
10
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
11
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
12
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
13
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
14
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
15
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
16
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
17
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
18
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
19
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
20
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
21
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
22
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
23
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
24
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
25
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
26
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
27
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
28
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
29
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
30
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
31
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
32
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
33
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
34
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
35
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
36
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
37
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
38
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
39
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
40
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
41
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
42
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
43
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
44
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
45
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
46
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
47
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
48
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
49
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
50
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
51
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
52
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
53
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
54
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
55
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
56
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
57
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
58
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
59
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedBlockEnd.gif)
再看 CacheModel 是如何处理的:
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
0 2
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
0 3
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
0 4
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
0 5
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
06
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
07
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
08
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
09
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockStart.gif)
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ContractedSubBlock.gif)
10
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/InBlock.gif)
11
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
12
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedSubBlockEnd.gif)
13
![](http://lifei114.javaeye.com/admin/blogs/7F84EE9E-1140-4202-B3A6-2168FFE828E1_files/ExpandedBlockEnd.gif)
controller 是实现以下接口的类
public interface CacheController
实现以下几种:
FifoCacheController
LruCacheController
MemoryCacheController
OSCacheController
再看看具体的实现,如MemoryCacheController的:
private Map cache = Collections.synchronizedMap(new HashMap());
1 publicvoid flush(CacheModel cacheModel) {
2 cache.clear();
3 }
其它的几种实现,也基本大致如此,不在具体贴代码了。
从上面的代码分析可以看出 IBatis 的缓存的更新机制大概如下:
执行 update,insert,delete 等操作时,触发对应的事件,注册的事件响应此操作,根据XML配置的缓存,对其数据做清空操作,也就是这个缓存中的数据全部清空,而不是
清空某一个 Key对应的值,即如我更新了一个 id= 5的数据,则这个缓存中的数据全部将清空。这样倒很简单也很彻底,由此带来的问题就很多了,如果你的 update等相关的操作太频繁了,这里的缓存则失去意义,且加大了系统本身的开销。因此,我认为对于更新不是很频繁的数据可以用 IBatis自身的缓存机制,如果是很频繁的数据就不要使用 IBatis 自身的缓存。举例说明:
0 2 < flushInterval hours ="24" />
0 3 < flushOnExecute statement ="insertProduct" />
0 4 < flushOnExecute statement ="updateProduct" />
0 5 < flushOnExecute statement ="deleteProduct" />
0 6 < property name ="size" value ="1000" />
0 7 </ cacheModel >
0 8 < statement id ="getProductList" parameterClass ="int" cacheModel ="product-cache" >
0 9 select * from PRODUCT where PRD_CAT_ID = #value#
10 </ statement >
如果你配置了以上操作,如果做了 insert_product,updateProduct,deleteProduct 中的任何一个操作,都将清空缓存 product-cache 中的所有数据,也就是getProductList方法将执行数据库操作,不能从缓存中获取数据。
最后一句,大家不要对 IBatis 的缓存抱太大的希望,虽然我们的系统中使用的是 IBatis。