为了喷mybatis我下载了mybatis源码

东坡下载 2011年12月10日 12:14:09

      久闻mybatis/ibatis大名今天终于爆发了,找了一堆mybatis的讨论。。。这部分大多是关乎sql写在xml之类的

      看了下mybatis的高速缓存的讨论。。。这部分无不例外的在分享缓存的配置。。。包括缓存实现。。。缓存过期策略。。。

      LRU。。。FIFO。。。

      如果说在xml里面写sql。。并且在上一堆dtd描述。。并且声称这样便于dba维护sql。。可以直接把写好的sql copy到xml里面去。。可以统一管理。 好吧,这些都属于个人习惯,无所谓。

      只不过我在想把这些sql变成方法,例如最简单的一个:

  1.       <select id=”getUserList” resultMap="UserResult" cacheModel=”user-cache”>  
  2.       select * from USER  
  3.       </select> 
  4.       变成:
  5.       public UserResult getUserList(){
  6.       return baseDao.find("select * from USER");
  7.       }

      我了解的太少,还没能看出这样有什么分别。关于这个,我只是有点点疑惑。(当然,你可以把这些写在一个类里面,便于你们的DBA维护)

      。。。。。。。。。

      作为一个ORM框架,除了面向对象查询 如JPA之类的,还有一个不得不提的东西:缓存。

      在我为缓存头痛的时候,我努力的寻找mybatis缓存的做法。毕竟这么多人使用的框架一定可以学习一下缓存的实现。

      在我输入关键词:ibatis 缓存/mybatis 缓存 看过基本上找到并且有时间去看的文章之后,我心里产生了一个疑问:为什么这些人来来去去都是讲的LRU、FIFO这些东西,或者贴出了这么一段精妙绝伦的代码:

      Java代码  

  1.       public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {  
  2.       if (ms != null) {  
  3.       Cache cache = ms.getCache();  
  4.       if (cache != null) {  
  5.       flushCacheIfRequired(ms);  
  6.       cache.getReadWriteLock().readLock().lock();  
  7.       try {  
  8.       if (ms.isUseCache() && resultHandler == null) {  
  9.       CacheKey key = createCacheKey(ms, parameterObject, rowBounds);  
  10.       final List cachedList = (List) cache.getObject(key);  
  11.       if (cachedList != null) {  
  12.       return cachedList;  
  13.       } else {  
  14.       List list = delegate.query(ms, parameterObject, rowBounds, resultHandler);  
  15.       tcm.putObject(cache, key, list);  
  16.       return list;  
  17.       }  
  18.       } else {  
  19.       return delegate.query(ms, parameterObject, rowBounds, resultHandler);  
  20.       }  
  21.       } finally {  
  22.       cache.getReadWriteLock().readLock().unlock();  
  23.       }  
  24.       }  
  25.       }  
  26.       return delegate.query(ms, parameterObject, rowBounds, resultHandler);  
  27.       }  

      当然,还有不少人画了一些UML例图来给苦难大众讲解 CachingExecutor是如何工作的。

      我不懂UML,也不知道怎么为这些精妙的if else画用例图。我开始走向绝望:“为什么这群人来来去去仅仅关心这些东西?”

      于是乎我下载了mybatis的源码,还好其结构很清晰。我在想“mybatis是如何让缓存过期?”毕竟这个是缓存的关键所在,于是我找到了这个:

      Java代码  

  1.       public int update(MappedStatement ms, Object parameterObject) throws SQLException {  
  2.       flushCacheIfRequired(ms);  
  3.       return delegate.update(ms, parameterObject);  
  4.       }  
 

      然后我又看到了这个:

      Java代码  

  1.       private void flushCacheIfRequired(MappedStatement ms) {  
  2.       Cache cache = ms.getCache();  
  3.       if (cache != null) {  
  4.       if (ms.isFlushCacheRequired()) {  
  5.       tcm.clear(cache);  
  6.       }  
  7.       }  
  8.       }  

      我很震惊,就这么样的。整个Cache被clear了。很简洁。哦不,是根本不带任何烦杂的处理,干脆利落的干掉了缓存的老巢。

      MappedStatement到底是何方神圣,虽然不知道也没看也看不明白(和传闻中的一样,不带一丝注释),但是据我猜测加上看到的一些mybatis的配置。

      我想mybatis把一个xml/namespace的sqlMap 装进了一个Cache,然后。。。没有然后了。

      这不禁的让我想到了看到的动画片里面感到疑惑不解的是为什么一个小飞船biu的一下巨大的战舰就爆了。

      。。。。。。。。。。。。。。

      对于这种缓存,我想到了这么一个场景。a用户查询得到查询缓存,b用户update自己的东西。a用户的查询缓存又挂了,重新查询得到查询缓存。

      当然,mybatis的缓存是大家的,不分你我他。

      。。。。。。。。

      如果,你真的有那么一些更新不频繁的接口。我建议使用spring的缓存,有clear方法。针对整个方法/事物。