该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-10
久闻mybatis/ibatis大名今天终于爆发了,找了一堆mybatis的讨论。。。这部分大多是关乎sql写在xml之类的
看了下mybatis的高速缓存的讨论。。。这部分无不例外的在分享缓存的配置。。。包括缓存实现。。。缓存过期策略。。。
LRU。。。FIFO。。。
如果说在xml里面写sql。。并且在上一堆dtd描述。。并且声称这样便于dba维护sql。。可以直接把写好的sql copy到xml里面去。。可以统一管理。 好吧,这些都属于个人习惯,无所谓。 只不过我在想把这些sql变成方法,例如最简单的一个:
我了解的太少,还没能看出这样有什么分别。关于这个,我只是有点点疑惑。(当然,你可以把这些写在一个类里面,便于你们的DBA维护)
。。。。。。。。。 作为一个ORM框架,除了面向对象查询 如JPA之类的,还有一个不得不提的东西:缓存。
在我为缓存头痛的时候,我努力的寻找mybatis缓存的做法。毕竟这么多人使用的框架一定可以学习一下缓存的实现。
在我输入关键词:ibatis 缓存/mybatis 缓存 看过基本上找到并且有时间去看的文章之后,我心里产生了一个疑问:为什么这些人来来去去都是讲的LRU、FIFO这些东西,或者贴出了这么一段精妙绝伦的代码:
public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { if (ms != null) { Cache cache = ms.getCache(); if (cache != null) { flushCacheIfRequired(ms); cache.getReadWriteLock().readLock().lock(); try { if (ms.isUseCache() && resultHandler == null) { CacheKey key = createCacheKey(ms, parameterObject, rowBounds); final List cachedList = (List) cache.getObject(key); if (cachedList != null) { return cachedList; } else { List list = delegate.query(ms, parameterObject, rowBounds, resultHandler); tcm.putObject(cache, key, list); return list; } } else { return delegate.query(ms, parameterObject, rowBounds, resultHandler); } } finally { cache.getReadWriteLock().readLock().unlock(); } } } return delegate.query(ms, parameterObject, rowBounds, resultHandler); }
当然,还有不少人画了一些UML例图来给苦难大众讲解 CachingExecutor是如何工作的。 我不懂UML,也不知道怎么为这些精妙的if else画用例图。我开始走向绝望:“为什么这群人来来去去仅仅关心这些东西?”
于是乎我下载了mybatis的源码,还好其结构很清晰。我在想“mybatis是如何让缓存过期?”毕竟这个是缓存的关键所在,于是我找到了这个:
public int update(MappedStatement ms, Object parameterObject) throws SQLException { flushCacheIfRequired(ms); return delegate.update(ms, parameterObject); }
然后我又看到了这个:
private void flushCacheIfRequired(MappedStatement ms) { Cache cache = ms.getCache(); if (cache != null) { if (ms.isFlushCacheRequired()) { tcm.clear(cache); } } }
我很震惊,就这么样的。整个Cache被clear了。很简洁。哦不,是根本不带任何烦杂的处理,干脆利落的干掉了缓存的老巢。
MappedStatement到底是何方神圣,虽然不知道也没看也看不明白(和传闻中的一样,不带一丝注释),但是据我猜测加上看到的一些mybatis的配置。 我想mybatis把一个xml/namespace的sqlMap 装进了一个Cache,然后。。。没有然后了。
这不禁的让我想到了看到的动画片里面感到疑惑不解的是为什么一个小飞船biu的一下巨大的战舰就爆了。
。。。。。。。。。。。。。。 对于这种缓存,我想到了这么一个场景。a用户查询得到查询缓存,b用户update自己的东西。a用户的查询缓存又挂了,重新查询得到查询缓存。 当然,mybatis的缓存是大家的,不分你我他。
。。。。。。。。 如果,你真的有那么一些更新不频繁的接口。我建议使用spring的缓存,有clear方法。针对整个方法/事物。
欢迎对喷 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-12-11
建议在没有深入了解和实践之前,不要轻易发表“顶”和“踏”的看法。
1、MappedStatement代表一条SQL语句配置,上述代码缓存的是该SQL标识和查询参数对应的查询结果。 2、对于单表的DAO,可以使用代码生成接口,配置成注解形式,不产生XML。 3、一般自己写的动态SQL才会放到XML文件里(非单表DAO)。 |
|
返回顶楼 | |
发表时间:2011-12-11
不要用框架自带任何缓存
这些缓存都是通用行的 无法满足你的业务 实在要上缓存的话 自己写好了 |
|
返回顶楼 | |
发表时间:2011-12-11
最后修改:2011-12-11
晕 有什么可喷的呢。。。
而且ls的说的很对啊 开源的东西都是很基础的工作而已 好多还都要用别的方法呢 不至于的来回喷。。。 |
|
返回顶楼 | |
发表时间:2011-12-11
ylucifer 写道 建议在没有深入了解和实践之前,不要轻易发表“顶”和“踏”的看法。
1、MappedStatement代表一条SQL语句配置,上述代码缓存的是该SQL标识和查询参数对应的查询结果。 2、对于单表的DAO,可以使用代码生成接口,配置成注解形式,不产生XML。 3、一般自己写的动态SQL才会放到XML文件里(非单表DAO)。 饿,即便是没有深入了解和实践。 我说的几个地方一点错都没有。 sql写在xml 或者注解上面就是我说的个人爱好问题。 MappedStatement = 一条sql配置也包括缓存地点。一个sqlMap 对应一个 缓存。update 操作直接清空缓存。 我喷的是缓存方面的处理没有理会个人爱好的问题。 缓存在针对具体的业务的时候才会起巨大的帮助,但是假如你的项目不属于那种报表型的。改造下其实也有较大的提升。 |
|
返回顶楼 | |
发表时间:2011-12-11
对于你提到的缓存、SQL统一管理好,还是混杂在程序中好等等……
这些讨论点先不展开,我只想问楼主一个问题:你理想的持久层框架是什么呢?能举个例子么? |
|
返回顶楼 | |
发表时间:2011-12-11
george_space 写道 对于你提到的缓存、SQL统一管理好,还是混杂在程序中好等等……
这些讨论点先不展开,我只想问楼主一个问题:你理想的持久层框架是什么呢?能举个例子么? 参见我的blog,还在一步一步完善中。 |
|
返回顶楼 | |
发表时间:2011-12-11
哥们,你们平常的项目就是:select * from USER 这样的sql语句吗?如果就这么一行,是啊,放代码里也挺好,可实际开发中有若干行sql,你一行一行的拼,带有多少肮脏的引号,哪个方便,一目了然啊,mybatis的缓存管理用的是oscache,a用户重新取得cache,b用户在取,这有什么问题吗?你觉得会线程不安全吗?你知道oscache对缓存是如何管理的吗?通过配置,oscache更新时可以先锁定更新的线程,然后其它读取线程才会读,也就是使用同步,不过,mybatis是否提供这种配置,我还没有看到过。mybatis省略了烦杂的setter方法,的确简化了jdbc的操作。
|
|
返回顶楼 | |
发表时间:2011-12-12
哇哈哈,果然出现了oscache 以及oscache的用法介绍。
|
|
返回顶楼 | |
发表时间:2011-12-12
广告贴...
|
|
返回顶楼 | |