|
原帖由 yulihua49 于 2008-11-18 16:22 发表 ![]()
现在大家都喜欢Hibernate的啊,要写优雅的数据库持久化啊。
现在,我的C程序员可以只写应用逻辑啦,不必关心SQL,只要知道这20来个函数就行了。
以前那种 应用逻辑的小草淹没在访问逻辑的森林里的情况改善多了。
呵呵,这个帖子好热啊。
我周围很多朋友搞java,都推崇hibernate等ORM的框架;
目的就是自动把数据库的表映射成对象;
然后业务的实现,就通过这些对象进行处理;
说白了,hibernate的作用主要有两个:
1.把对数据库的操作对象化,也就是比直接用存储过程之类更OO;更容易扩展和维护;
2.与数据库无关性,不直接操作数据库,所以数据库可以是msssql,mysql,oracle;而系统不需要做什么改动;
说老实话,我没用过hibernate,而且我基本都是些c/s的系统;开发工具是delphi;
不过,我感觉系统开发,视图+存储工程(包) 就够了;
在客户端,查询,我从不操作表,基本都是事先写好视图,客户端直接 select * from 视图 where...a=:1 and b=:2 ....;
( 如果在客户端直接操作表,sql太复杂,比如 select a.a1....b.b1 from a,b,c where ... and exists() and... where ....
很容易写错,而且没法用select * ; 很多书上都说,尽量不用select * ;我却很推重;不仅这样简单,而且动态,客户端不用做映射;
而且经过我测试下来,没觉得select * 比 select 各个字段效率相差多少;)
业务点,全部用存储工程(包) ;
涉及到简单的表的更改操作,用delphi自带的功能完成(也就是让系统自动生成sql提交数据);
没感觉到非要使用ORM之类的东西;
而且,我觉得在项目中,数据库的变动时常用的事情,经常加些字段之类的;
这些在我的系统里,只要简单的修改一下视图,客户端程序不要做任何修改;
但是对于HiberNate这样的框架,就要重新映射,重新生成对象;
当然,对于b/s系统的开发我不熟悉,尝试过几次,开发的繁琐基本让我很难忍受,
举个简单的例子:
比如要实现 select * from vw1 ; 把数据显示在Grid上;
在b/s里,要把每个字段通过标签<>一个一个的定义出来 ,而且字段名必须每个不能错;
如果视图vw1发生改变,网页中的各个字段的标签也要一个一个的对应修改,错一个都不行,而且如果错了,只有运行期运行到那里才会发现错误;而且还要指定每个字段的宽度,居左居右,中文意义;各个字段的前后顺序;写的我快崩溃了,虽说这样一路写下来,也不是很复杂,但是这样绑定太“死”了; 以后数据库发生一点点变化,网页里跟者不停的修改代码;就算你用了hibernate这么先进的框架,但是这个工作少不了;我尝试过jquery,extjs,好像都省不了;
在用户体验上,Grid的数据显示可以说是在以数据库为核心的系统中,是重中之重的环节,如果这个开发太麻烦和僵化,那么我就不知道“敏捷”这这里有何体现;
而现在在c/s里,由于这么多年下来,可能也是因为积累了些东西,想上面的这个查询;
我会一句代码也不用写,就能实现:
1.自动把vw1视图中的各个字段搜索出来,自动生成查询条件;用户可以 实现 select * from vw1 where field1 like(=) :1 ;
2.在Grid上不需要定义各个字段,动态加载,vw1发生任何变化,都不需要做任何代码的编写;
而且Grid上能够“记忆”各个字段的宽度,各个字段间的位置顺序,某些字段可以设置成和(平均)统计;各个字段上可以做数据过滤;
这些不用写一句代码;由于数据库设计的时候,字段名一般不会是中文,鉴于oralce视图的字段可以加备注(mssql没有该功能),所以各个字段的中文显示就是通过视图的备注展现出来的,也不需要写任何一句代码;
再重新回到HiberNate 上;
1.它的最本质的作用是,是把对数据库的操作变成一个个的对象操作;其做法我觉得有点别扭;数据库是基于二维表的关系型数据库;本身可能不是基于对象的,硬通过一些手段,把它变成所谓的对象,感觉有点牵强附会,也许那一天数据库发生本质变化,本身表结构就是基于对象的,那才能做到真正的OO;现在做这样的“伪OO”,真的给开发提高效率,给维护带来方面吗? 而且这种“伪OO”还要做到数据库无关性,说白了,劈除性能的考虑,对它来说,Access和oracle是没有区别的;说白了,就是把数据库仅做数据存储用,其他的数据库的特性一概屏蔽;
2. oracle的Tom Kittle曾经说过,既然选择了oracle,就要多多的里利用他的特性,否着你为何化那么多钱买这款数据库;
比如oracle的分析函数sum() over() lead/lag, 分组统计rollup,rownum的妙用,connect by 嵌套 ,with 子句嵌套查询 等等;
这些功能放着不用,用所谓的“伪对象”实现,是不是过于复杂了,而且效率也不高。
3.系统的并发,事务,互锁等如何很好的控制,不同的数据库,其并发机制也不一样,我一般把业务写在数据库的package里(mssql好像仅有存储过程),如果并发控制不好,就可以调整存储过程的程序实现;而且客户端我基本不控制事务;需要循环的,就直接把数组作为参数传进来,事务全部在存储过程内部控制,所以客户端很简单;也没有所谓的中间业务层,或者说中间业务层,就是一堆包和存储过程;
4.系统的优化,人非圣贤,孰能无过;谁能保证写的程序是最优化的,一般情况下,如果执行一个操作本来就很快,也就不用考虑优化;
但是随这数据量的增长,业务的复杂;也许某几个关键操作,会运行的很慢;如果用hibernate里的一堆对象,层层嵌套下来,要找到瓶颈,很难;但是如果是存储过程实现,这个发现就简单了,oracle的手段太多了,比如可以用profiler,把过程里的每条sql所消耗的时间展现出来,马上就知道那几条sql需要优化;
5.就算用了HiberNate,可以“简化”开发人员对各种sql技巧的依赖,那么就果真能提高开发效率吗?而且hiberNate还自搞了一个HQL;
我不知道HQL比SQL简化多少,但是有必要简化吗?SQL本身就是面相结果的,已经够简单了,还要如何简化;再说HQL是个通用的功能,那么它就要适应于所有数据库,这样不是弱化各种不同的数据库的特性功能吗?这样做处了实现所谓的通用,却是牺牲了性能和开发效率;
6.所谓通用问题,HiberNate是数据库无关性,能够让开发人员较为方便的更换数据库;但是通用性不仅仅看数据库,万一前台开发工具变了呢,比如一开始用java,后来用.net,php ,ruby ;那不是一样大该程序; 但是如果把业务点都用存储过程实现;那么就算换了前台开发工具,也没有“撼动根基”;也就是说,业务点都用数据库自身实现,就可以弱化对前台工具的依赖;大家都知道,相对来说,数据库的变化较慢,而前台工具却是日新月异;
7.最后说一件关于SQL运行机制的问题,HiberNate说白了,它的所有数据操作不也是自动生成SQL实现的? 而且据说它生的SQL不够优化,有时候很复杂,不容易看懂;我有个疑惑,这种自动生成的SQL你放心吗?一个稍微复杂的操作,它可能是上百个sql实现的;如果用数据库的存储过程实现,客户端只用和数据库交互一次;而HiberNate却是上百次;这样不是既增加了服务端压力,也增加了客户端压力;
还有这些上百个sql对于oracle来说,可是未编译的动态sql,其效率和存储过程相比,可想而知;
我只是说了我的想法,或者说是疑惑,没有贬低HiberNate的意思;我也知道它肯定有它很好的地方,否着为何在java领域那么流行;
我说了这么多,说白了就是希望有人指出我的错误;毕竟做了那么多项目,都是“过分”的依赖于pl/sql了,技术上没有学习新东西;所以思想也一定很落伍;
[ 本帖最后由 qingyun 于 2009-5-2 12:11 编辑 ] |
|