其实标题起的太大,anyway, 实在是找不到合适的题目。
在OnV项目已经作了1年多了,有些感触,写下来以备以后整理之用。
好死不死负责Report这里,逻辑既复杂,Performance的要求又非常之高,与通常easy to code的J2EE其他模块有很大的不同。
项目技术背景:
OR Mapping Tool:
Hibernate 2.0
Web tier:
Struts 1.2
Report Tool:
Jasper Reports
构架没什么好说的,唯一特殊的是由于需求的关系,是multiple database (features and users两个dimensions上的multiple)
几点重要的经验教训:
1. Model Design一定要好,项目之初由于大家都比较缺乏经验,尤其是一些Model由刚毕业的fresh people来做,实在后果不堪设想。
这里其实很推荐Martin的那本J2EE企业构架的书,也就是说OR Mapping的一些指导原则。
key point:lazy loading很重要;model之间的关联尽可能是双向,即便由于有些原因不能增加Hibernate语法上的association(Object A中有Object B作为属性),那么最好也要有Objecd A中有一个ObjectBId,但相关联将给query 带来很大麻烦。 例如:如果需求有根据B的ID array去查询A,那么没有这种关系,则必须从Object B入手查询A,这就造成unnecessary的2个表join 查询,很耗费资源。
2. 尽可能地Batch操作,例如Batch save和loop save的操作,性能上天差地别。
3. 在类似Report的Query(意指查询条件复杂,数据量大),是不应当粗粒度操作的。一直觉得J2EE的一个特点就是,简化developers的工作,面向对象,并且粗粒度。但是在这种性质的查询里,如果粗粒度,结果就会导致性能的灾难。其实这个是老调重弹,2002年左右我记得CSDN上就有人在诟病J2EE说性能如何的差。其实关键是developers是否估计到Use scenario对粒度的影响。简化developers的工作是有限度的,OR mapping的工作也并不是为了使没有经验中学生就能够很容易的写出好的Enterprise application。其实数据更新也有类似的问题,例如无法update specific 的attribute而不得不更新整个Object,这个时候性能的差异就会体现出来,只不过大多数情况下,Object不会大到让人无法接受,也不会像Report query那样request大量的数据,所以这方面性能的影响,在一些系统中不会体现出来。
合理划分Query的group,真实的目的是减少一次查询中Join表的个数。Hibernate2的缺陷也可以有所规避(不能任意指定Join的方式)
如前所述,Report query很大程度上被Object Model Design所制约
还有别的一些杂感,例如Hibernate不能support View,动态mapping,都对提高Performance所能采取的stratagy做了限制。不过这些东西似乎在hibernate3中有了支持,还没有时间用,不过已经让team里的一个member去research一下hibernate3的new feature