WEB开发网
开发学院软件开发Java iBatis 使用 OSCache 作缓存与 java.io.FileNotFo... 阅读

iBatis 使用 OSCache 作缓存与 java.io.FileNotFoundException 异常

 2009-09-22 00:00:00 来源:WEB开发网   
核心提示: 无法写某个文件,文件找不到,iBatis 使用 OSCache 作缓存与 java.io.FileNotFoundException 异常(3),一开始我也以为是 OSCache 那方出了什么差错,所以 Google 的关键词都偏重于 OSCache FileNotFoundExcption,关

无法写某个文件,文件找不到,一开始我也以为是 OSCache 那方出了什么差错,所以 Google 的关键词都偏重于 OSCache FileNotFoundExcption。后来结合 iBatis 才艰难的 Google 到了这个:http://osdir.com/ml/java.ibatisdb.devel/2004-06/msg00079.html,也有同问的:http://forums.opensymphony.com/thread.jspa?messageID=673372&。说句外话,搜索这方面内容时,能时刻为党说话的 Baidu 就不太擅长了,基本上用它来搜索 ‘儿子’ 和药品是无敌的了。

看了前面那个贴子,拍了下脑袋,其实早该醒悟的,不就是说的:'e:\OSCache\cache\application\1991729862|2162672802|5|Product_31getById|62996507|_49_50_51_52_53_54_55_56_57select_64id,_68name,description_85as_88desc1_94_95from_100test_105product_113where_119id_122=_124_125_126_127_128_129_130 文件无法写吗。去看看 e:\OSCache\cache\application 目录中,没有这里提到的文件。如果你试图去手工建立这么一个文件,文件名有多长且不说,但 Windows 肯定要提示你:文件名不能包含下面任何字符: \ / : * ? " < > | 。对啦,问题就出在 iBatis 为 OSCache 生成的文件名上。

开源的东西对我们使用者有什么好处,就是能完全窥探到源代码呀。我的习惯是开源的组件,总会下载到相应的源代码摆在它的身边。于是 Debug/Step Into 吧,发现前面那个长长的文件名其实就是 OSCache 用来缓存 iBatis 查询得到结果(注:iBatis 被缓存的粒度没 Hibernate 的缓存细,不是以实体对象为单位,而是以查询结果为单位,所以会出现第一次查询的 id=2 or id=3 的结果被缓存了,第二次查询 id=2 时还是从数据库中取得情况) 的 Key,这个 Key 是基于查询语句(含查询条件) 生成的。实现类是 iBatis 的 com.ibatis.sqlmap.engine.cache.CacheKey,它的 toString() 方法返回值就是文件名:

1.public String toString() {
2.  StringBuffer returnValue = new StringBuffer().append(hashcode).append('|').append(checksum);
3.  for (int i=0; i < paramList.size(); i++) {
4.    returnValue.append('|').append(paramList.get(i));
5.  }
6. 
7.  return returnValue.toString();
8.}

上面代码生成的文件名就可能包含竖线符号("|"),这在 Windows 平台是不允许的,在 Linux 下是不受此约束的。为了能让 iBatis 在使用文件缓存时保持平台独立性,我们的 Fix 办法可使在该 toString() 方法最后返回时把 | 换成都能够接受的符号,比如 -,即把 return 语句改为:

return returnValue.toString().replace('|', '-');

可以把修正编译好的 CacheKey.class 替换掉 iBatis jar 包中的相应位置的 CacheKey.class,或者若是 Web 应用,可直接放在 classes 目录中正确位置上,因为 classes 中散装的类文件要优先于 jar 包中的类得到加载。

问题需解决了,但还是得注意几点:

1. 即使是使用其它缓存实现,也都是由这个 CacheKey 来生成 Key 的,所以若有可能使用其它缓存组件,缓存文件时同样有可能出现类似的问题。

2. 如果 CacheKey 在结合 SQL 和 参数生成的文件名过长可能也会是个问题,受限于不同的文件系统。设置的缓存目录不要过深,适时完全自定 toString() 方法。

3. 还有,关于是从缓存中取数据还是从数据库取得问题,这个 CacheKey 的 equals() 方法值得细究,这是我的后话了。

上一页  1 2 3 

Tags:iBatis 使用 OSCache

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接