论坛首页 入门技术论坛

我为什么选择 iBatis 而不是 Hibernate(对于正在选型的人的建议)

浏览 69628 次
该帖已经被评为新手帖
作者 正文
   发表时间:2007-01-01  
非常感谢 cjmm 中肯的回帖。其中的大部分观点我都相当认同。

但是我想我先前对 3.1/3.3 地描述可能不是太清楚。所以你的方案并不太适合。我重新详细地描述了一下这两个问题。如果方便的话请重新看看。
0 请登录后投票
   发表时间:2007-01-01  
flyspider 写道

帖子里是人家对ORM的一些看法,怎么就成了“臆想和猜测”了?软件设计过程中必然存在审时度势的折衷,走极端往往过犹不及,如果您很会用hibernate,请给兄弟们说说你如何让Hibernate很少在POJO与RDBMS Model之间转换?

如果采用“领域建模-〉写XDoclet或ejb3.0标注-〉自动生成数据库模式”的流程来使用hibernate就可以免去这个麻烦
0 请登录后投票
   发表时间:2007-01-01  
jiming 写道

  
3. iBatis 可以进行细粒度的优化

   3.1 比如说我有一个表,这个表有几个或者几十个字段,我需要更新其中
       的一个字段,iBatis 很简单,执行一个sql
       UPDATE TABLE_A SET column_1=#column_1# WHERE id=#id#
       但是用 Hibernate 的话就比较麻烦了,缺省的情况下 hibernate 会更新所有字段。
       当然我记得 hibernate 有一个选项可以控制只保存修改过的字段,但是我不太确
       定这个功能的负面效果。

  这个用hql (也就是我刚刚说得bulk update)或者用native sql都可以实现你的需求。
  当然也可以用触发器机制。
    hql:
         String hqlUpdate = "update A a set culumn_1 = :column1 where id=:id"
               Query query = session.createQuery(hqlUpdate);
                  query.setParameter("column1", column1);
                   query.setParameter("id", id);
                     query.excuteUpdate();

   3.3也是同样的处理方式。
 
jiming 写道
    
   3.2 我需要列出一个表的部分内容,用 iBatis 的时候,这里面的好处是可以少从数据
     库读很多数据,节省流量
       SELECT ID, NAME FROM TABLE_WITH_A_LOT_OF_COLUMN WHERE ...

     3.2.1 一般情况下
     Hibernate 会把所有的字段都选出来。比如说有一个上面表有8个字段,
     其中有一两个比较大的字段,varchar(255)/text。上面的场景中我为什么要把他
     们也选出来呢?

     3.2.2 用 hibernate 的话,你又不能把这两个不需要的字段设置为 lazy load,因
     为还有很多地方需要一次把整个 domain object 加载出来。这个时候就能显现出
     ibatis 的好处了
    


    可以对单个字段设为lazy load,在需要一次加载出来的时候再把lazy属性给取消,查询时直接设置
    load mode
 
jiming 写道
  
     3.2.3 Hibernate 还有一个方案,就是生成 javabean/map/object[](感谢
     leelun/cjmm),但是这样的话就可能会产生大量的多余 class。map/object[] 的方式
     应该不错,我比较喜欢这种方式。
       

 
     不需要产生大量多余class,呵呵。设置属性的时候不是所有属性都需要设置的,你还是可以使用原来map的class。
     map成javabean的时候除了使用constructor之外还有一种方式是直接使用setter方法,使用alias成属性名加上setResultTransformer(Transformers.aliasToBean(XXX.class))

    个人建议,你还是对hibernate多加了解再对hibernate进行评述。

    hibernate最大的缺点还是学习曲线过长,其他没啥好弊病的。原始的方式还是高层次的方式都已经提供了很好的支持。
0 请登录后投票
   发表时间:2007-01-01  
jiming 写道
非常感谢 cjmm 中肯的回帖。其中的大部分观点我都相当认同。

但是我想我先前对 3.1/3.3 地描述可能不是太清楚。所以你的方案并不太适合。我重新详细地描述了一下这两个问题。如果方便的话请重新看看。

3.1没有什么负面作用,自己用反射也能实现。
3.3DML可以解决。如果只是简单的处理的话差一条也无所谓,如果是批量的话hibernate性能确实不如ibatis。但是我觉得问题的关键还是性能是否符合需求,而不是简单的性能比较。
0 请登录后投票
   发表时间:2007-01-01  
jiming 写道
3. iBatis 可以进行细粒度的优化

3.1 比如说我有一个表,这个表有几个或者几十个字段,我需要更新其中
的一个字段,iBatis 很简单,执行一个sql
UPDATE TABLE_A SET column_1=#column_1# WHERE id=#id#
但是用 Hibernate 的话就比较麻烦了,缺省的情况下 hibernate 会更新所有字段。
当然我记得 hibernate 有一个选项可以控制只保存修改过的字段,但是我不太确
定这个功能的负面效果。

3.2 我需要列出一个表的部分内容,用 iBatis 的时候,这里面的好处是可以少从数据
库读很多数据,节省流量
SELECT ID, NAME FROM TABLE_WITH_A_LOT_OF_COLUMN WHERE ...

3.2.1 一般情况下
Hibernate 会把所有的字段都选出来。比如说有一个上面表有8个字段,
其中有一两个比较大的字段,varchar(255)/text。上面的场景中我为什么要把他
们也选出来呢?

3.2.2 用 hibernate 的话,你又不能把这两个不需要的字段设置为 lazy load,因
为还有很多地方需要一次把整个 domain object 加载出来。这个时候就能显现出
ibatis 的好处了

3.2.3 Hibernate 还有一个方案,就是生成 javabean/map/object[](感谢
leelun/cjmm),但是这样的话就可能会产生大量的多余 class。map/object[] 的方式
应该不错,我比较喜欢这种方式。

3.3 如果我需要更新一条记录(一个对象),如果使用 hibernate,需要现把对
象 select 出来,然后再做 update。这对数据库来说就是两条 sql。而 iBatis
只需要一条 update 的 sql 就可以了。减少一次与数据库的交互,对于性能的
提升是非常重要。


3.1, 3.3 build update解决,不赘述
3.2 lazy load
3.2.2 lazy load与整个domain object load并不冲突,即使不用lazy loading,也可以通过不同映射或其他方法解决
一般情况下,hibernate可以在90%的应用上给开发上带来数倍的效率提高,剩余的部分也在致力不降低效率,整体来看,比ibatis提升的效率还是很多的
0 请登录后投票
   发表时间:2007-01-01  
dada 写道
jiming 写道
非常感谢 cjmm 中肯的回帖。其中的大部分观点我都相当认同。

但是我想我先前对 3.1/3.3 地描述可能不是太清楚。所以你的方案并不太适合。我重新详细地描述了一下这两个问题。如果方便的话请重新看看。

3.1没有什么负面作用,自己用反射也能实现。
3.3DML可以解决。如果只是简单的处理的话差一条也无所谓,如果是批量的话hibernate性能确实不如ibatis。但是我觉得问题的关键还是性能是否符合需求,而不是简单的性能比较。


hibernate在性能上最大的问题不是update操作,而是insert操作。呵呵。对insert的限制比较大。还有一些过于严格的检查使得某些数据库优化方面的设计不适用。具体可以见我的space,不过现在连不上。
0 请登录后投票
   发表时间:2007-01-01  
综合治理-最美
0 请登录后投票
   发表时间:2007-01-01  
总有朋友说 hibernate 的开发效率比ibatis 高,对此我非常的不认同。我想我们举个小例子来比较一下。

以我第4页中贴出的代码为例,我需要更新用户的 status 字段。

我只需要在 UserDao.java 中添加方法

在配置文件中 user.xml 添加

     public int updateStatus(int mender_id, byte status, long id) {  
         Map params = new HashMap();  
         params.put("status", status);  
         params.put("id", id);  
         return template.update("updateUserStatusById", params);  
     }  
      


   <update id="updateUserStatusById" parameterClass="java.util.Map">  
   UPDATE auth_user SET   
     status=#status#  
     , updated_date=#updatedDate#  
     , touch_date=#touchDate#  
   WHERE id=#id#  
   </update>  
  



瞧,多简洁,多优雅。

但是诸位所提到的 hibernate 地解决方案却没有一个如此优雅的。直接使用 hsql/nativeSQL 不错,但是他会影响到系统的数据库一致性。这可是我认为唯一需要考虑使用 hibernate 的情况:)

对于我的第三部分提出的问题,很多位高手都给出了方案。但是正向我在正文中指出的那样,我不是说 hibernate 做不到,而是使用hibernate的方案都相对比较复杂。

我希望大家能再说的时候能够给出一小段代码:)这样更清楚,而且大家说hibernate 很快,我写上面的代码之花了很短的时间,远比我写文字块多了,我向大家也可以花一点点写点代码来说明观点。

我的一贯主张就是程序才是程序员的语言。










0 请登录后投票
   发表时间:2007-01-01  
勘误

但是诸位所提到的 hibernate 地解决方案却没有一个如此优雅的。直接使用 hsql/nativeSQL 不错,但是他会影响到系统的数据库移植性。这可是我认为唯一需要考虑使用 hibernate 的情况:)
0 请登录后投票
   发表时间:2007-01-01  
简单一点说,很多人选择A而不选择B,都是因为先入为主。

客观的说,从长远来考虑,还是应该采用HB。比如现在我们的系统,如果需要部署到oracle/mssql/db2/mysql/pg/hsql/firebird,所需要做的只是加一个JDBC驱动,再改一下hb.cfg.xml中连接数据库的配置。这一点是IBATIS无论如何也做不到的。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics