近日,上论坛中,看了Ibatis和Hibernate的帖子,看后,心里觉得的憋闷,不说不快, 其实Robbin之前有一个帖子,都说过了,但在这里,我想更细化一下: 

    1. 库表关系的复杂度,首先取决于需求,不取决于设计,设计能力强的人,也要遵守库表设计的规范,从巴克斯三个范式上,原则上也要遵守。不能说用了Hibernate,自己的库表设计能力就强了。不能为了用Hibernate,就去一味批判复杂的关系不对。复杂的关系设计对不对,首先取决于是否有复杂的需求,其次才取决于设计者的能力。

    2. 只要你用的是关系数据库,就必须要明白,为什么叫关系数据库,而不叫面向对象数据库,把面向对象的那些观点,拿到库表设计上,后期维护和调优上,你要担起责任,不能让开发人员替早期决策人员擦屁股。我见过有的人,打着OO和扩展性的旗号,硬生生的把一个表,拆成了三个表,而这三个表,本来,只需要增加一个类型字段,再做一些冗余,就可以是一个表。现在查询时,还要把这三个表Union到一块来查。当需求变更时,增加一个字段,不仅要改变三个类,还要改变三个表,简直是乱伦。

    3.One-One的库表设计,对于DBA来讲,并不是一个best practice的设计。不能为了Hibernate,刻意把大表拆成小表,再用几个小类,做成One-One的映射关系。整体性,是不能随便的分割,毕竟开发人在调试、测试和维护的时候,更喜欢看数据库里的数据,本来一个SQL,就查出来,现在要到多个表中去查。

    4. 增删改存的实体维护
       Ibatis比不上Hibernate,说实在话,现在让我写SQL来维护一个多对多关系的实体维护,我都要考虑上半天,别说写代码了。

    5. 你需要写原生SQL吗
       首先你要确认,你项目的要求不需要写原生SQL,再来讲Ibatis和Hibernate的好坏,在写原生SQL上,特别是动态生成的SQL,ibatis比Hiberante有得一拼,ibatis就像一个模板一样,将SQL写在配置文件当中,集中配置,特别方便技术领导者监控项目成员写的SQL好坏,而且没有什么学习曲线,就写SQL就完事了。

       有人会说,Hibernate也支持写SQL,但是写代码当中,就失去了原来基于Hibernate的DAO的简洁性。那个DAO一点也不简洁,如果你将动态拼SQL的代码也放在DAO当中,那个DAO就会充斥大量的If 。。Else。。之类的语句,一坨一坨的,非常的壮观。

       还有人会说,Hibernate也支持命名查询,将SQL写在映射文件当中,但是命名查询,只支持占位符固定的情况,也就是说,where a = ? and b = ? and c=?,是三个问号,就是三个问号,传参时,少一个都不行。但是很多项目的查询,都是动态的,也就是说用户选了这个查询条件,才会生成这个占位符的。

       Hibernate办不到。


       还有人会说,我自己用Hibernate写一个框架,也可以做到,那你写的绝对可能比Ibatis好,也可能差,你要造轮子,谁来拦不着。
  

    5. 调优
       早期调优,有些Bad SQL,其实在code review阶段,只要看看Ibatis的SQL配置文件,就可以扼杀掉的,如果使用HSQL,可能不会被发现,因为它不仅隐藏在代码当中,有的时候,还需要程序跑起来,通过日志打印出SQL或者通过其它工具如P6Spy来看的出来。

       后期调优,既然是后期调优,我想就一定是遇到了瓶颈,可能要在库表上做冗余,可能要检查那些Bad SQL,可能要修改代码,可能要动用DBA层次上的一些调优手段,那么调优越深入,Ibatis的优势就越能体现出来,比如说增加临时表,中间表,增加冗余字段等。

    6. 开发速度
      
       如果项目当中,没有一个Hibernate高手,你的项目又相对的复杂,不仅有复杂的库表关系,还有大量的报表查询,那么使用Hibernate,速度上逊于Ibatis.

       问题在于,怎么样算是一个Hibernate高手,别看论坛上,那么多人,群情激奋的在说Hibernate的好,有谁真的是高手?

     7. 平台移植性
       如果你的项目要做产品,而且打算基于多个数据库平台的发布,使用Hiberante是没有说了。

    8. 维护性
       如果不考虑移植性,Ibatis的可维护不差于Hibernate,库表变动引起实体类变动时,HSQL也会有改动,有人说不用改,说这话的那个人可能整天只会有select * ,如果ibatis也是这样写,也不用动了。

       HSQL好阅读吗,From order,确实很简单,但实际当中,这跟拿HelloWord做例子,有什么区别?

     
   
    9. 我在实际项目当中的运用
    项目背景:
       我自己从Hibernate2开始使用,我现在也不认为我是Hibernate高手,我也没有时间去钻研Hibernate,更深的东西,我也不喜欢坐在开发人员旁边老半天,去帮他们解决Hibernate遇到的问题,因为我自己还有很多事要做。

       我的项目当中,在Hibernate方面,还有一个比我更强的人,他也很烦去看Hibernate打印出来的sql,看上老半天,再调上老半天,项目进度,嗖嗖的过去了。

       水平越高的人,任务越重,很少有时间和耐心去解决一般性的问题。

    最终的运用:

       在基于Spring的容器事务管理之下,
       增、删、改、存及在事务中的查询,使用Hibernate。
       非事务性的查询及报表,都用Ibatis,维护非常的直观方便,开发速度上也快很多。

       我觉得现在技术换代很快,使用一项技术,首先是要快速的解决问题,然后要学习他的思想,那些整天死抱着Hibernate,自认为学习到ORM的设计技巧的人,就去继续的学吧。

       我已经会用Hibernate的一些方面,我觉得够用就行了,犯不上,天天钻研HSQL,如果有时间,我觉得躺在草坪上看看Unix的编程艺术,看看代码大全,看看Oracle的编程艺术,比看Hibernate的SB书要惬意多了。

       简单能够带来快乐,用过EJB,再用Spring的人,都有体会,那简直是一种思想上的重生。


       Ibatis的设计者认为,在新的项目当中,可以使用Hibernate,在旧的遗留项目当中,可以使用Ibatis,不明白,他为什么说这样的话,这与新旧项目有什么区别? 用不用Ibatis,我觉得对我上面说的几点有关。

 

 

  

 

 


评论
davexin 2007-06-05
这个帖子太好了,本人用了hibernate后,感觉不是很好,并不见得用hibernate开发就快速。用不好的话,反而带来了无穷的麻烦
drinkjava 2007-06-02
seapigxie 写道
drinkjava首先请不要进行人身攻击,也请仔细看我的问题。首先,这是我两年前的经历,当初对Hibernate确实不是很熟悉。我hibernate 学的怎样,是我自己的事情。那hibernate 既然允许有这样的设计,就应该考虑到项目中采用此种设计所造成的后果。也就是要能帮助设计人员规避风险,但hibernate的文挡中也没有类似的说明。不过我现在坚持一点,查询是尽量绕开hibernate。当然,我也很想听听大家的高见。drinkjava,你有好的思路,也不妨摆出来大家看看。

Sorry,我不是想针对你的,我只是来气啊,不是生你的气,而是Hibernate太难学了!上面是句反话,你没看出来。正常的用法谁都知道,谁都会说什么你的Hibernate没用好,是你没有从对象概念出发,它的xxx细节你还没学会...,这些我都听腻了,我只不过照抄过来代替那此高手们吓唬你而已...(顺提,你的那种做法,JDBC取出的内容只能用于查询,不能用于修改,否则会破坏Hibernate的二级缓存,这不适合复杂的又要查询又要修改的业务逻辑,至于你那9个表的问题,正统的OO式的解决方法我水平不够,无法解答,不过我倒有另一种思路,见下)
两年前我刚接触Hibernate的时候,也非常抵触,觉得掌握它不容易,尤其不适合是那些数据库概念已根深蒂固,OO思维很差的人。但它的那些功能如不用写SQL,对象式访问,跨数据库,缓存等等,却让人垂涎三尺,当时甚至有开发一个自已的简易持久层的想法,当然后来因难度太大而作罢,现在Hibernate这么流行,自已所在的项目中也引入了Hibernate,这种想法更是不了了之,直到有一天,忽然想到如果不用Hibernate的关联,一切又可以变得简单,又可以回到熟悉的数据建模时代,上网一查,也有人已经在这样用
( 见贴子http://www.javaeye.com/topic/82107),
突然间有了一种"蓦然回首那人却在灯火阑珊处"的感觉,原来当年我想自已编的持久层,用Hibernate也可以做到!
seapigxie 2007-06-01
drinkjava 写道
seapigxie 写道
呵呵,大家的讨论好精彩。
我也说下我的体会。接触Hibernate也快三年了,刚开始玩的时候确实不好搞。但到了一定的时候,又遇到了性能问题,关键是查询。我以前的一个系统,是在接触hibernate不久的时候做的。由于业务相对复杂,表结构也比较复杂,用到了继承映射,用的是每个子类一张表(Table per subclass)的策略,父类加子类总共是九个,相对应的是九张table,而且父类还有和其他类存在one-to-many的关系(这个暂且抛开放在一边)。起初以为比如要查一个子类对应的信息,hibernate只会关联father table,实质也就是one-to-one的一个关联查询,但后来上线一段时间,数据量大了(而且有历史数据),系统相当慢。我去查看最终的SQL,把我吓了个半死。最终的查询成了九张表的关联查询(而且每张表的数据量都是在10W以上的)。后来全部改成JDBC才解决问题。后来还发现了很多查询方面的问题(比如one-to-one强制关联加载)。
经此一役,我对Hibernate查询的效率就不敢恭维了。现在我对列表信息的查询全部直接通过JDBC(sql是在一个抽象类里面自动拼装,程序员基本不要对sql进行处理,返回结果也是封装成值对象),只用hibernate对单个对象进行操作(这点hibernate还是很方便的)。如果有关联查询,我就在程序的service层进行处理,尽量绕开关联查询,我想着要笛卡尔积,心里就慌,尤其是数据量大的业务表进行之间。
呵呵,本人是半路出家,但现在也在开始搭些小系统的框架了,但水平很有限,望大家多指教。
这个网站能有今天的成长,真是可喜可贺了。04年的时候还好嫩的。

三年了,你的Hibernate怎么学的?Hibernate没有问题,是你的设计思路有问题。

drinkjava首先请不要进行人身攻击,也请仔细看我的问题。首先,这是我两年前的经历,当初对Hibernate确实不是很熟悉。我hibernate 学的怎样,是我自己的事情。那hibernate 既然允许有这样的设计,就应该考虑到项目中采用此种设计所造成的后果。也就是要能帮助设计人员规避风险,但hibernate的文挡中也没有类似的说明。不过我现在坚持一点,查询是尽量绕开hibernate。当然,我也很想听听大家的高见。drinkjava,你有好的思路,也不妨摆出来大家看看。
drinkjava 2007-06-01
suyulin6688 写道
spring的JdbcTemplate也是很强悍的,

对hibernate不是很熟悉的话,用用这个也是不错的。

又是一个思维陷阱,看到太多遍了,不用Hibernate就一下将人推到jdbc(或ibatis),这是一种走极端的做法,就好象误了飞机就叫人去骑驴车,而不是想一想有没有其它的办法。
我觉得这样用要比JdbcTemplate强悍多了:
http://www.javaeye.com/topic/82107
suyulin6688 2007-05-31
spring的JdbcTemplate也是很强悍的,

对hibernate不是很熟悉的话,用用这个也是不错的。
drinkjava 2007-05-30
seapigxie 写道
呵呵,大家的讨论好精彩。
我也说下我的体会。接触Hibernate也快三年了,刚开始玩的时候确实不好搞。但到了一定的时候,又遇到了性能问题,关键是查询。我以前的一个系统,是在接触hibernate不久的时候做的。由于业务相对复杂,表结构也比较复杂,用到了继承映射,用的是每个子类一张表(Table per subclass)的策略,父类加子类总共是九个,相对应的是九张table,而且父类还有和其他类存在one-to-many的关系(这个暂且抛开放在一边)。起初以为比如要查一个子类对应的信息,hibernate只会关联father table,实质也就是one-to-one的一个关联查询,但后来上线一段时间,数据量大了(而且有历史数据),系统相当慢。我去查看最终的SQL,把我吓了个半死。最终的查询成了九张表的关联查询(而且每张表的数据量都是在10W以上的)。后来全部改成JDBC才解决问题。后来还发现了很多查询方面的问题(比如one-to-one强制关联加载)。
经此一役,我对Hibernate查询的效率就不敢恭维了。现在我对列表信息的查询全部直接通过JDBC(sql是在一个抽象类里面自动拼装,程序员基本不要对sql进行处理,返回结果也是封装成值对象),只用hibernate对单个对象进行操作(这点hibernate还是很方便的)。如果有关联查询,我就在程序的service层进行处理,尽量绕开关联查询,我想着要笛卡尔积,心里就慌,尤其是数据量大的业务表进行之间。
呵呵,本人是半路出家,但现在也在开始搭些小系统的框架了,但水平很有限,望大家多指教。
这个网站能有今天的成长,真是可喜可贺了。04年的时候还好嫩的。

三年了,你的Hibernate怎么学的?Hibernate没有问题,是你的设计思路有问题。
seapigxie 2007-05-30
呵呵,大家的讨论好精彩。
我也说下我的体会。接触Hibernate也快三年了,刚开始玩的时候确实不好搞。但到了一定的时候,又遇到了性能问题,关键是查询。我以前的一个系统,是在接触hibernate不久的时候做的。由于业务相对复杂,表结构也比较复杂,用到了继承映射,用的是每个子类一张表(Table per subclass)的策略,父类加子类总共是九个,相对应的是九张table,而且父类还有和其他类存在one-to-many的关系(这个暂且抛开放在一边)。起初以为比如要查一个子类对应的信息,hibernate只会关联father table,实质也就是one-to-one的一个关联查询,但后来上线一段时间,数据量大了(而且有历史数据),系统相当慢。我去查看最终的SQL,把我吓了个半死。最终的查询成了九张表的关联查询(而且每张表的数据量都是在10W以上的)。后来全部改成JDBC才解决问题。后来还发现了很多查询方面的问题(比如one-to-one强制关联加载)。
经此一役,我对Hibernate查询的效率就不敢恭维了。现在我对列表信息的查询全部直接通过JDBC(sql是在一个抽象类里面自动拼装,程序员基本不要对sql进行处理,返回结果也是封装成值对象),只用hibernate对单个对象进行操作(这点hibernate还是很方便的)。如果有关联查询,我就在程序的service层进行处理,尽量绕开关联查询,我想着要笛卡尔积,心里就慌,尤其是数据量大的业务表进行之间。
呵呵,本人是半路出家,但现在也在开始搭些小系统的框架了,但水平很有限,望大家多指教。
这个网站能有今天的成长,真是可喜可贺了。04年的时候还好嫩的。
Chamjoneu 2007-05-28
OneEyeWolf 写道
Chamjoneu 写道
lz 写道
5. 你需要写原生SQL吗
首先你要确认,你项目的要求不需要写原生SQL,再来讲Ibatis和Hibernate的好坏,在写原生SQL上,特别是动态生成的SQL,ibatis比Hiberante有得一拼,ibatis就像一个模板一样,将SQL写在配置文件当中,集中配置,特别方便技术领导者监控项目成员写的SQL好坏,而且没有什么学习曲线,就写SQL就完事了。

有人会说,Hibernate也支持写SQL,但是写代码当中,就失去了原来基于Hibernate的DAO的简洁性。那个DAO一点也不简洁,如果你将动态拼SQL的代码也放在DAO当中,那个DAO就会充斥大量的If 。。Else。。之类的语句,一坨一坨的,非常的壮观。

还有人会说,Hibernate也支持命名查询,将SQL写在映射文件当中,但是命名查询,只支持占位符固定的情况,也就是说,where a = ? and b = ? and c=?,是三个问号,就是三个问号,传参时,少一个都不行。但是很多项目的查询,都是动态的,也就是说用户选了这个查询条件,才会生成这个占位符的。

Hibernate办不到。


还有人会说,我自己用Hibernate写一个框架,也可以做到,那你写的绝对可能比Ibatis好,也可能差,你要造轮子,谁来拦不着。



说个只有少数人才不知道的

where a = ? and b = ? and c=?, 可以写成
where (a = ? or a is null) and (b = ? or b is null) and (c=?,or c is null)

这样的namedquery可以统一注册在xml里, 并且通过plain object 来作为criteria 绑定

这样既满足了oo也可以应付比较特殊的要求



这种SQL就是那种弱智程序员极度易犯的错误。
自己找个Oracle的书,或者找个DBA来看看,a is null 是非常不推荐的一种做法。明明没有这种条件,偏要加一个让索引失效的条件,还要自做聪明,典型的让DBA找抽型SQL。


可能是表述上有点问题, 这里用的是hql
<query name="paymentQuery">
<![CDATA[
SELECT
DISTINCT(record.employee),
record.employee.number,
record.employee.name,
SUM(record.payment)

FROM
ProduceRecord record

WHERE
(record.createDate >= :startDate OR :startDate = NULL) AND
(record.createDate <= :endDate OR :endDate = NULL) AND
(record.paidFlag = :paidFlag OR :paidFlag = NULL) AND
(record.employee = :employee OR :employee = NULL)

GROUP BY
record.employee
]]>
</query>
mingj 2007-05-27
yanhua 写道
引用
人们对于超出自己理解能力之外的观点,往往本能的产生强烈的排斥……

去年我们做了一个应用,用了Hibernate,为了提高性能,当删除几条记录的时候采用了要求原生的SQL,大致写成这样:
deletet from XXX where id='1' or id='2' or .....



为什么不用batchUpdate?
OneEyeWolf 2007-05-23
Chamjoneu 写道
lz 写道
5. 你需要写原生SQL吗
首先你要确认,你项目的要求不需要写原生SQL,再来讲Ibatis和Hibernate的好坏,在写原生SQL上,特别是动态生成的SQL,ibatis比Hiberante有得一拼,ibatis就像一个模板一样,将SQL写在配置文件当中,集中配置,特别方便技术领导者监控项目成员写的SQL好坏,而且没有什么学习曲线,就写SQL就完事了。

有人会说,Hibernate也支持写SQL,但是写代码当中,就失去了原来基于Hibernate的DAO的简洁性。那个DAO一点也不简洁,如果你将动态拼SQL的代码也放在DAO当中,那个DAO就会充斥大量的If 。。Else。。之类的语句,一坨一坨的,非常的壮观。

还有人会说,Hibernate也支持命名查询,将SQL写在映射文件当中,但是命名查询,只支持占位符固定的情况,也就是说,where a = ? and b = ? and c=?,是三个问号,就是三个问号,传参时,少一个都不行。但是很多项目的查询,都是动态的,也就是说用户选了这个查询条件,才会生成这个占位符的。

Hibernate办不到。


还有人会说,我自己用Hibernate写一个框架,也可以做到,那你写的绝对可能比Ibatis好,也可能差,你要造轮子,谁来拦不着。



说个只有少数人才不知道的

where a = ? and b = ? and c=?, 可以写成
where (a = ? or a is null) and (b = ? or b is null) and (c=?,or c is null)

这样的namedquery可以统一注册在xml里, 并且通过plain object 来作为criteria 绑定

这样既满足了oo也可以应付比较特殊的要求



这种SQL就是那种弱智程序员极度易犯的错误。
自己找个Oracle的书,或者找个DBA来看看,a is null 是非常不推荐的一种做法。明明没有这种条件,偏要加一个让索引失效的条件,还要自做聪明,典型的让DBA找抽型SQL。
magic007 2007-05-22
deletet from XXX where id='1' or id='2' or...
这样的语句本身就有问题。or本来就可能会引起全表扫描,其次,如果这里的ID不是字符型,而是其他类型,很可能就是全表扫描了。当然速度会慢了。

我一向认同“性能是设计出来的”这样的观点,我非常不赞同系统上线后再调优这样的说法,上线后发现性能问题,很可能是设计上的问题已经没办法调优。

每种类型的应用都有它合适的架构,我所接触的一些应用系统,系统间的接口都有四五个甚至七八个,这样的系统,二级Cache的使用,涉及到的问题就非常多了,可以说在这种情况下就不适合使用。
Chamjoneu 2007-05-22
lz 写道
5. 你需要写原生SQL吗
首先你要确认,你项目的要求不需要写原生SQL,再来讲Ibatis和Hibernate的好坏,在写原生SQL上,特别是动态生成的SQL,ibatis比Hiberante有得一拼,ibatis就像一个模板一样,将SQL写在配置文件当中,集中配置,特别方便技术领导者监控项目成员写的SQL好坏,而且没有什么学习曲线,就写SQL就完事了。

有人会说,Hibernate也支持写SQL,但是写代码当中,就失去了原来基于Hibernate的DAO的简洁性。那个DAO一点也不简洁,如果你将动态拼SQL的代码也放在DAO当中,那个DAO就会充斥大量的If 。。Else。。之类的语句,一坨一坨的,非常的壮观。

还有人会说,Hibernate也支持命名查询,将SQL写在映射文件当中,但是命名查询,只支持占位符固定的情况,也就是说,where a = ? and b = ? and c=?,是三个问号,就是三个问号,传参时,少一个都不行。但是很多项目的查询,都是动态的,也就是说用户选了这个查询条件,才会生成这个占位符的。

Hibernate办不到。


还有人会说,我自己用Hibernate写一个框架,也可以做到,那你写的绝对可能比Ibatis好,也可能差,你要造轮子,谁来拦不着。



说个只有少数人才不知道的

where a = ? and b = ? and c=?, 可以写成
where (a = ? or a is null) and (b = ? or b is null) and (c=?,or c is null)

这样的namedquery可以统一注册在xml里, 并且通过plain object 来作为criteria 绑定

这样既满足了oo也可以应付比较特殊的要求
Chamjoneu 2007-05-22
LZ 写道
5. 你需要写原生SQL吗
首先你要确认,你项目的要求不需要写原生SQL,再来讲Ibatis和Hibernate的好坏,在写原生SQL上,特别是动态生成的SQL,ibatis比Hiberante有得一拼,ibatis就像一个模板一样,将SQL写在配置文件当中,集中配置,特别方便技术领导者监控项目成员写的SQL好坏,而且没有什么学习曲线,就写SQL就完事了。

有人会说,Hibernate也支持写SQL,但是写代码当中,就失去了原来基于Hibernate的DAO的简洁性。那个DAO一点也不简洁,如果你将动态拼SQL的代码也放在DAO当中,那个DAO就会充斥大量的If 。。Else。。之类的语句,一坨一坨的,非常的壮观。

还有人会说,Hibernate也支持命名查询,将SQL写在映射文件当中,但是命名查询,只支持占位符固定的情况,也就是说,where a = ? and b = ? and c=?,是三个问号,就是三个问号,传参时,少一个都不行。但是很多项目的查询,都是动态的,也就是说用户选了这个查询条件,才会生成这个占位符的。

Hibernate办不到。


还有人会说,我自己用Hibernate写一个框架,也可以做到,那你写的绝对可能比Ibatis好,也可能差,你要造轮子,谁来拦不着。



说个只有少数人才不知道的

where a = ? and b = ? and c=? 可以写成
where (a = ? or a is null) and (b = ? or b is null)and (c=?,or b is null)

并且 可以统一写在namequeries.xml 里 用plain object 直接绑定 作为查询条件

这样 既可以满足OO也可以 解决很特殊的需求
Chamjoneu 2007-05-22
ray_linn 写道
heaven 写道
好长一贴,总体看来,貌似
orm cache > sqlmap query cache> database cache
也就是越靠近应用越有效,
但是我们平时最常用也最可控的还是基于业务分析的service cache,
具体的就是用aop来做service proxy来实现,这种方式也满地都是,

个人觉得sqlmap比orm封装了更多的基于sql的业务逻辑,因此sqlmap cache其实比orm的cache更接近业务层面,所以 sqlmap cache 某些情况一定是好于orm cache的,当然越接近业务的控制,越需要加上对业务分析,也就越多了一些维护的工作,



我觉得是懂得db cache的人太少,oralce的SGA/PGA分几类,是如何分配的,能说清楚的就没几个,所以更谈不上有效利用了。


Web server 与 database server 之间的通讯开销 才是 orm cache 和 database cache 的楚河汉界

同样也适用batch query, hb默认使用batch, 那它去比拼单条执行的sql当然是不公平的
Chamjoneu 2007-05-22
抛出异常的爱 写道
不是不能调,是如果你一年什么事都没作,好意思一年要个几十W么


确实 这是公司最佳实践的标准 有开发 更要有维护
robbin 2007-05-13
juyin 写道
OneEyeWolf 写道

基于良好的ORM架构的二级缓存,当然比没有的强。我也没有表示反对。
但我也不能装明白,讨论清楚,总比说半截话,舒服多了。

我也做过缓存级的底层模块。对于缓存及缓存产品,以前这个论坛上也有很多讨论的很精辟的帖子,我也从中学到了很多知识。

我前面也说过,不能拿着Cache当锤子,到处都是钉子。

关键是命中率,有多高,这个需要考量和测试。

论坛模型仍然是一个相对容易缓存的模型。

说果说一个订单模型,当用户查询完后,它很少再会被查第二次,如果是基于LRU算法的,它很容易就会被换出缓存的。





看了前面几页,
不过我很想听听robbin对这上面这段的解释:)

如果一个订单很少被查到,例如在整整一天的时间,这个订单只被查询了一次,这说明了一个问题:订单表根本没有必要做缓存,因为他的使用频率非常低。

其次,你可以把缓存开大一些,2G够不够?4G够不够,不够?还可以8GB阿?现在买一台服务器配8G内存也没有多少钱。
juyin 2007-05-13
OneEyeWolf 写道

基于良好的ORM架构的二级缓存,当然比没有的强。我也没有表示反对。
但我也不能装明白,讨论清楚,总比说半截话,舒服多了。

我也做过缓存级的底层模块。对于缓存及缓存产品,以前这个论坛上也有很多讨论的很精辟的帖子,我也从中学到了很多知识。

我前面也说过,不能拿着Cache当锤子,到处都是钉子。

关键是命中率,有多高,这个需要考量和测试。

论坛模型仍然是一个相对容易缓存的模型。

说果说一个订单模型,当用户查询完后,它很少再会被查第二次,如果是基于LRU算法的,它很容易就会被换出缓存的。





看了前面几页,
不过我很想听听robbin对这上面这段的解释:)
liuwangxia 2007-05-12

ltian 写道:
我对你们的实现感到吃惊和新奇,是一种思路,不过在电费系统中的计算量非常大,要计算的东西非常多,涉及到的大表很多,涉及到的相互关联的对象多达几十个。都弄到内存里用对象的方法进行计算恐怕工作量大,而且查找一个对象的速度会不会存在问题?如果那样的话,为何不开大数据库的缓存呢,同样利用数据库的方式去查找记录也很快阿,不知道你们这个系统涉及到多少张大表?

1) 涉及到的大表很多,不等于计算时所需的数据很多,计算之前取数据时尽量不要加载无用的数据。我们的系统主要涉及POS销售流水、POS退货流水、采购进货单、采购退货单、报损单、联营合同、销售挂账单等等,其中POS销售流水最大,还涉及到几张结果表。加载的数据根据计算的需要进行重新组织了结构,与库表并非一一对应,但是根据主键来保存结果。我觉得表多不是问题,只要内存够用就很可以了。
2) 查找一个对象的速度非常之快,因为计算之前已经转换成了 Map 了,直接 get 就行了。即使开大数据库的缓存,利用数据库的方式去查找记录的速度也无法和内存的 Map 相比。
3) 我们的系统用存储过程计算时,实际步骤也是先加载所有需要计算的数据,只不过是加载到内存表中,再就是一边计算一边保存,没有像新方法那样所有计算完成后一次保存。我估计存储过程主要慢在计算和循环上,存储过程的游标速度无法与 Java 的 for 循环相比,数学运算也慢,因为我原来用的是 MS SQL Server ,至于其他数据库,很容易写出一个测试来验证。
lihy70 2007-05-11
NetBus 写道
lihy70 写道
NetBus 写道
讨论个跑题的问题:

我用使用Hibernate的时候,有时候会有第三方程序在更新数据库,这时候如何刷新Hibernate的Cache?


呵呵,个人认为这应该是一个“异想天开”的问题,
虽一点不懂hibernate的cache策略,但几乎同时可以说: It's impossible!


怎么不可能嘛,就拿一个cms系统来说,录入和发布肯定是分开的。我在发布时候肯定要cache模板啊什么的。如果录入或者其它更新了模板内容,这时候如何通知Hibernate刷新Cache?

这种情况下是不是使用memoryCache会更好一些?如果是dba更新了数据库,MemoryCache是不是也无能为力?

不好意思,前面说错了,所以把前面那个帖子(之前,没看到你发的这个帖子)。
我本来的想说的是hibernate(或cache自身)不可能自动刷新。
当然,你可以通过调用hibernate或cache的接口手动更新,如果有这样的接口。
ltian 2007-05-11

liuwangxia 写道:

ltian 写道:

零售的计算怎么能和电费的计算相比!你的那个太简单了!电费计算一次要设计到N多表,N多的算法.

电费的计算我不懂,所以不好判断哪个更加复杂。但是我们的开发实践表明,至少在我们现有的应用中新方法要快得多。
至于电费的计算用新方法是否要慢些,建议您测试一下之后再得出结论。

补充:用 Java 做成本核算有个缺点,就是 BigDecimal 没有运算符,只能用 add subtract multiply divide 等方法,代码可读性很差。

我对你们的实现感到吃惊和新奇,是一种思路,不过在电费系统中的计算量非常大,要计算的东西非常多,涉及到的大表很多,涉及到的相互关联的对象多达几十个。都弄到内存里用对象的方法进行计算恐怕工作量大,而且查找一个对象的速度会不会存在问题?如果那样的话,为何不开大数据库的缓存呢,同样利用数据库的方式去查找记录也很快阿,不知道你们这个系统涉及到多少张大表?


OneEyeWolf
搜索本博客
我的相册
33aa1154-2beb-4678-a4b1-83e5b0406ef7-thumb
SNV30982
共 3 张
最近加入圈子
存档
最新评论