论坛首页 入门技术论坛

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

浏览 69622 次
该帖已经被评为新手帖
作者 正文
   发表时间:2007-01-01  
downpour 写道

一张表有30个字段,你用ibatis去做一次insert试试?不过在查询方面,iBatis的确有很多优势的地方。


我只能说,典型的活人给尿憋死,人的手是用来创造工具的,不只是用来打键盘的.

0 请登录后投票
   发表时间:2007-01-01  
iceant 写道
我不喜欢Hibernate,也不喜欢所谓的OO,大家可以冷静的想想,有多少系统是真正使用的 OO 方式来设计和实现的呢

OO只是一种思考方式,它可以有助于开发人员了解和分析系统,抽象出系统中的各种元素。但是真正实现,还是要使用传统的各种方法与技术。OO不能解决你所有的问题,言必谈OO,不一定真正的了解OO.

我说个简单点的,有谁能用纯OO实现一个系统,然后又能很好的控制事务的? 

Hibernate 也是一样,它也有自己适用的范围和区间。Hibernate 要应用得好,真的是要花很多的时间,我是从JDBC开始写应用的,所以我不喜欢Hibernate,因为它在实现系统时的思维方式与我的不一样~ 我使用 RDBMS 做为 Storage,Hibernate 将 RDBMS 中的 Table 转换为 POJO,在做系统时,我要不停的在 RDBMS Model 和 POJO 之间转换,为的是了解系统底层发生了什么,系统是否能进一步优化,为了能更好的让 Hibernate 发挥效率,我要试很多不同的方式,最终才能确定哪一种在这个情况下可能更合适~ 说句实话,累啊~ 感觉就像是在计算机里不停的切换两个线程~

iBatis简单,最重要的是,我的模型是用 RDBMS 描述的,我能继续用 RDBMS 的方式来处理数据,对于我这种人来说,存贮过程在很多情况下仍然是最好的选择。也许有人会说,你们把业务放在存贮过程中,可扩展性很差。呵~ 所以这就要看你应用的 scope 了,如果性能很重要,使用存贮过程还是很好的选择。而且对我们的应用,除了 Oracle,不可能用别的数据库。

我觉得很多人把精力花在系统的可扩展性和可移植性上了,就我接触过的系统来说,这方面的需求还是很少的。一来有些系统的生命周期非常短,没有必要;再来,系统运行的时间长了,对它进行替换的成本是很高的。

因此我偏向于对一个具体的应用,采取最有效最简单的方式来完成。就像如果需求只是要打印 123,那就 System.out.println("123”)就好了,不要再来个 System.out.println(124-1)

Hibernate 对于熟悉它的人,是一样非常好的工具,Hibernate 的作者也说过,只要是 Hibernate Team 的人,做出来的系统肯定性能不会差~ 但是不熟悉的人就很难说了~ 我建议使用它的人还是读读它的代码,别盲目使用。很难相象一个程序员,对它的工具做了什么都不知道,还能用好它。

Hibernate 还有一样我最不能接受的,就是它的作者。他根本不能接受别人的意见,只想听奉承。对于别人提出的意见示而不见。最有名的就是在 web 系统里 redeploy 时, Hibernate 会因为内存不能得到释放,引起 web 容器down掉(OutofMemoryExcepiton)。很多人都报告过这个问题,但是开发团队从来不承认这是 Hibernate 引起的。一下说是 commons-log.jar的问题,一下又说是 dom4j的问题,一下又说是 tomcat 的问题(已经证实jboss/weblogic/websphere也会出这问题),一下又说是cglib的问题,呵~ 反正理由多得是~ 就是不关 Hibernate 的问题~ 有人在 JIRA 里开了个BUG,被作者以 Session没有 close 为由给close了,他连测都没测一下~ 我经过测试,证明就算是调用了Session.close还是一样会出现这个问题,只要把Hibernate.jar去掉,一切就可以很好的工作。 Hibernate 的论坛上本来有一个贴子就是说这个问题的,很多人都关注过,但是后来不知道为什么这个贴子不在了。这个问题存在很久了,到最新版的Hibernate也没有解决。我很难理解,JBoss为什么要把它引入到 AS 里面去,它就不怕 Hibernate 引起 redeploy 失效吗?这和JBoss AS的 7*24 不相符啊~


最后我想说,在没有ORM的时候,我们一样能做出系统,而且性能也不差,系统一样可以维护,为什么一定要用ORM?有个朋友说,这些技术只是让程序员舒服了,但是软件不见得就强壮多少。我想这句话很有道理

通篇是你的臆想和猜测
另外,如果你"要不停的在 RDBMS Model 和 POJO 之间转换",说明你还不知道如何用hibernate
0 请登录后投票
   发表时间:2007-01-01  
引用
从你的分析来看,我觉得你可以稍微花点时间在如何解决你所分析出来的问题上面。你所提到的问题都是可以解决的。

ORM框架各有各的好处,不用过分强调谁行谁不行。老实说,iBatis在做持久化的笨拙就令人受不了。一张表有30个字段,你用ibatis去做一次insert试试?不过在查询方面,iBatis的确有很多优势的地方。


这几个问题不是说 hibernate 无法解决,而是他的解决方案太难看,或者执行效率太低了。
0 请登录后投票
   发表时间:2007-01-01  
/**
 *
 * $Id$
 * Flag: 0.5
 *
 */


package com.jiming.community.shoubo.auth.persistence.sqlmapdao.base;

import java.util.List;
import java.util.Map;
import java.sql.Date;
import java.sql.Timestamp;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import jm.lib.common.db.SqlUtil;
import jm.lib.common.db.Order;
import jm.lib.util.DateUtil;
import jm.lib.util.StrUtil;
import jm.lib.common.db.ConditionOperation;
import jm.lib.common.db.SearchClause;
import jm.lib.common.db.SimpleSearchCondition;
import jm.lib.collections.map.TinyMap;

import com.jiming.community.shoubo.auth.domain.User;
import com.jiming.community.shoubo.auth.persistence.iface.UserDao;


/**
 * @author Jiming Liu
 *
 */
public abstract class BaseUserSqlMapDao extends SqlMapClientDaoSupport implements UserDao {

    private static final Log logger = LogFactory
        .getLog(BaseUserSqlMapDao.class);

    protected SqlMapClientTemplate template = this.getSqlMapClientTemplate();

    // Get element by unique keys -- begin
    public User getById(int user_id, long id) {
        return (User)template.queryForObject("getUserById", id);

    }

    public User getByName(int user_id, String name) {
        return (User)template.queryForObject("getUserByName", name);

    }


    // Get element by unique keys -- end


    /**
     * equals <code>insert(value, true)</code>
     * @param mender_id
     * @param value
     * @return
     */
    public Object insert(int mender_id, User value) {
        return insert(mender_id, value, true);
    }


    @SuppressWarnings("unchecked")
    public List<User> getList(int user_id) {
        return (List<User>)template.queryForList("getUser", null);
    }


    public int getTotalCount() {
        Integer result = (Integer)template.queryForObject("getUserCount", null);
        return result.intValue();
    }


    public int getCount(int user_id, SearchClause clause) {
        Integer result = (Integer)template.queryForObject("getUserCountWithCondition", clause);
        return result.intValue();
    }

    @SuppressWarnings("unchecked")
    public List<Long> getId(int user_id, SearchClause clause) {
        return (List<Long>)template.queryForList("getUserIdWithCondition", clause);
    }

    @SuppressWarnings("unchecked")
    public List<Map> list(int user_id) {
        return (List<Map>)template.queryForList("listUser", null);
    }


    public List<Map> list(int user_id, int startIndex, int pageSize) {
        SearchClause clause = new SearchClause();
        clause.setStartIndex(startIndex);
        clause.setPageSize(pageSize);
        return list(user_id, clause);
    }


    @SuppressWarnings("unchecked")
    public List<Map> list(int user_id, SearchClause clause) {
        List result = template.queryForList("listUserWithCondition", clause);
        return (List<Map>)result;
    }

    @SuppressWarnings("unchecked")
    public List<Map> list(int user_id, String[] columns, SearchClause clause) {
        Map params = new TinyMap(2);
        params.put("clause", clause);
        params.put("columns", SqlUtil.getColumnsInSql(columns));
        return (List<Map>)template.queryForList("listUserCustomized", params);
    }


    // Delete element by unique keys -- begin
    @SuppressWarnings("unchecked")
    public int deleteById(int mender_id, long id) {
        return template.delete("deleteUserById", id);
    }

    @SuppressWarnings("unchecked")
    public int deleteByName(int mender_id, String name) {
        return template.delete("deleteUserByName", name);
    }

    // Delete element by unique keys -- end



    /**
     * equals <code>update(mender_id, value, true)</code>
     * @param value
     * @return
     */
    public int update(int mender_id, User value) {
        return update(mender_id, value, true);
    }



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















    @SuppressWarnings("unchecked")
    public List<Map> listIdName(int user_id, String name) {
        Map params = new TinyMap();
        params.put("name", name);
        return (List<Map>)template.queryForList("user_listIdName", params);
    }

    @SuppressWarnings("unchecked")
    public List<Map> listIdNameByDescGroup(int user_id, String name) {
        Map params = new TinyMap();
        params.put("name", name);
        return (List<Map>)template.queryForList("user_listIdNameByDescGroup", params);
    }





    @SuppressWarnings("unchecked")
    public int addVisitCount(int user_id, int amount, long id) {
        Map params = new TinyMap();
        params.put("id", id);
        params.put("amount", amount);
        return template.update("user_addVisitCount", params);
    }

}

















0 请登录后投票
   发表时间:2007-01-01  
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">





<!-- Created by Jiming Liu -->
<!-- Flag: 0.5 -->
<!-- Including primary operation definition of auth_user-->
<sqlMap namespace="auth_user">
  <typeAlias alias="type_User" type="com.jiming.community.shoubo.auth.domain.User" />
  
  <resultMap id="user" class="type_User">
    <result property="id" column="id" />
    <result property="name" column="name" />
    <result property="password" column="password" />
    <result property="mid" column="mid" />
    <result property="msisdn" column="msisdn" />
    <result property="regDate" column="reg_date" />
    <result property="updatedDate" column="updated_date" />
    <result property="lastVisitDate" column="last_visit_date" />
    <result property="birthday" column="birthday" />
    <result property="score" column="score" />
    <result property="country" column="country" />
    <result property="province" column="province" />
    <result property="city" column="city" />
    <result property="gender" column="gender" />
    <result property="hasBlog" column="has_blog" />
    <result property="status" column="status" />
    <result property="postCount" column="post_count" />
    <result property="replyCount" column="reply_count" />
    <result property="groups" column="groups" />
    <result property="sig" column="sig" />
    <result property="intro" column="intro" />
    <result property="productId" column="product_id" />
    <result property="pagesize" column="pagesize" />
    <result property="creatorId" column="creator_id" />
    <result property="touchDate" column="touch_date" />
    <result property="ratio" column="ratio" />
    <result property="money" column="money" />
  </resultMap>

  <!-- Get element by unique keys - begin -->
      

  <select id="getUserById" parameterClass="long" resultMap="user">
    SELECT * FROM auth_user 
     WHERE id=#value#
  </select>
    
      

  <select id="getUserByName" parameterClass="java.lang.String" resultMap="user">
    SELECT * FROM auth_user 
     WHERE name=#value#
  </select>
    
      

    
  <!-- Get element by unique keys - end -->

  <insert id="insertUser" parameterClass="type_User">
    INSERT INTO auth_user (
      name
      , password
      , mid
      , msisdn
      , reg_date
      , updated_date
      , last_visit_date
      , birthday
      , score
      , country
      , province
      , city
      , gender
      , has_blog
      , status
      , post_count
      , reply_count
      , groups
      , sig
      , intro
      , product_id
      , pagesize
      , creator_id
      , touch_date
      , ratio
      , money
    ) VALUES (
      #name#
      , #password#
      , #mid#
      , #msisdn#
      , #regDate#
      , #updatedDate#
      , #lastVisitDate#
      , #birthday#
      , #score#
      , #country#
      , #province#
      , #city#
      , #gender#
      , #hasBlog#
      , #status#
      , #postCount#
      , #replyCount#
      , #groups#
      , #sig#
      , #intro#
      , #productId#
      , #pagesize#
      , #creatorId#
      , #touchDate#
      , #ratio#
      , #money#
    )
    <selectKey resultClass="int" keyProperty="id" >
    SELECT @@IDENTITY AS id
    </selectKey>
  </insert>
  
  <select id="getUser" resultMap="user">
    SELECT * FROM auth_user
  </select>


  <select id="getUserCount" resultClass="java.lang.Integer">
    SELECT COUNT(1) FROM auth_user
  </select>


  <select id="getUserIdWithCondition"
    resultClass="long" parameterClass="searchClause">
    SELECT id FROM auth_user
    $clauseWithoutLimit$
    <isGreaterEqual property="startIndex" compareValue="0">
    LIMIT #startIndex#,#pageSize#
    </isGreaterEqual>
  </select>


  <!-- Delete element by unique keys - begin -->
  <delete id="deleteUserById" parameterClass="long">
    DELETE FROM auth_user 
     WHERE id=#value#
  </delete>
    
  <delete id="deleteUserByName" parameterClass="java.lang.String">
    DELETE FROM auth_user 
     WHERE name=#value#
  </delete>
    
    
  <!-- Delete element by unique keys - end -->


  
  <update id="updateUser" parameterClass="type_User">
  UPDATE auth_user SET 
    name=#name#
    , password=#password#
    , mid=#mid#
    , msisdn=#msisdn#
    , reg_date=#regDate#
    , updated_date=#updatedDate#
    , last_visit_date=#lastVisitDate#
    , birthday=#birthday#
    , score=#score#
    , country=#country#
    , province=#province#
    , city=#city#
    , gender=#gender#
    , has_blog=#hasBlog#
    , status=#status#
    , post_count=#postCount#
    , reply_count=#replyCount#
    , groups=#groups#
    , sig=#sig#
    , intro=#intro#
    , product_id=#productId#
    , pagesize=#pagesize#
    , creator_id=#creatorId#
    , touch_date=#touchDate#
    , ratio=#ratio#
    , money=#money#
   WHERE id=#id#
  </update>
  
  
  
  
  
  
  
  
  
  
  
  
  
  // 上面的部分已经可以解决绝大部分的问题了
  // 下面的部分是为了细化的调优,不要因此认为 ibatis 配置很复杂,你可以忽略这部分
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <update id="updateUserStatusById" parameterClass="java.util.Map">
  UPDATE auth_user SET 
    status=#status#
    , updated_date=#updatedDate#
    , touch_date=#touchDate#
  WHERE id=#id#
  </update>
  
  
  <select id="listUser" resultClass="java.util.HashMap">
    SELECT id 
      , name 
      , msisdn 
      , reg_date AS regDate 
      , updated_date AS updatedDate 
      , last_visit_date AS lastVisitDate 
      , birthday 
      , score 
    FROM auth_user
  </select>

  


  
    
  <select id="user_listIdName" resultClass="java.util.HashMap" parameterClass="java.util.Map">
    SELECT id
      , name
     WHERE name = #name#
  </select>
  
  
  <update id="user_addVisitCount"  parameterClass="java.util.Map">
    UPDATE auth_user SET
      post_count=post_count+#amount#      
      WHERE id=#id#      
  </update>
  <update id="user_addVisitCountByIdName"  parameterClass="java.util.Map">
    UPDATE auth_user SET
      post_count=post_count+#amount#      
     WHERE id=#id#      
       AND name=#name#      
  </update>
  


  
    
  <select id="user_listIdName" resultClass="java.util.HashMap" parameterClass="java.util.Map">
    SELECT id
      , name
     WHERE name = #name#
  </select>
  
  

  
  <update id="user_addVisitCount"  parameterClass="java.util.Map">
    UPDATE auth_user SET
      post_count=post_count+#amount#      
     WHERE id=#id#      
  </update>

</sqlMap>







0 请登录后投票
   发表时间:2007-01-01  
上面的两个文件就是用 ibatis 的解决方案。

多优美。

本来想打包上传的,不知道为什么不能上传文件,所以直接贴代码了。

好像多贴了一个 xml 的代码,请 robbin 方便的话帮我把多余的删了吧,谢谢。
0 请登录后投票
   发表时间:2007-01-01  
daquan198163 写道
iceant 写道
我不喜欢Hibernate,也不喜欢所谓的OO,大家可以冷静的想想,有多少系统是真正使用的 OO 方式来设计和实现的呢

OO只是一种思考方式,它可以有助于开发人员了解和分析系统,抽象出系统中的各种元素。但是真正实现,还是要使用传统的各种方法与技术。OO不能解决你所有的问题,言必谈OO,不一定真正的了解OO.

我说个简单点的,有谁能用纯OO实现一个系统,然后又能很好的控制事务的? 

Hibernate 也是一样,它也有自己适用的范围和区间。Hibernate 要应用得好,真的是要花很多的时间,我是从JDBC开始写应用的,所以我不喜欢Hibernate,因为它在实现系统时的思维方式与我的不一样~ 我使用 RDBMS 做为 Storage,Hibernate 将 RDBMS 中的 Table 转换为 POJO,在做系统时,我要不停的在 RDBMS Model 和 POJO 之间转换,为的是了解系统底层发生了什么,系统是否能进一步优化,为了能更好的让 Hibernate 发挥效率,我要试很多不同的方式,最终才能确定哪一种在这个情况下可能更合适~ 说句实话,累啊~ 感觉就像是在计算机里不停的切换两个线程~

iBatis简单,最重要的是,我的模型是用 RDBMS 描述的,我能继续用 RDBMS 的方式来处理数据,对于我这种人来说,存贮过程在很多情况下仍然是最好的选择。也许有人会说,你们把业务放在存贮过程中,可扩展性很差。呵~ 所以这就要看你应用的 scope 了,如果性能很重要,使用存贮过程还是很好的选择。而且对我们的应用,除了 Oracle,不可能用别的数据库。

我觉得很多人把精力花在系统的可扩展性和可移植性上了,就我接触过的系统来说,这方面的需求还是很少的。一来有些系统的生命周期非常短,没有必要;再来,系统运行的时间长了,对它进行替换的成本是很高的。

因此我偏向于对一个具体的应用,采取最有效最简单的方式来完成。就像如果需求只是要打印 123,那就 System.out.println("123”)就好了,不要再来个 System.out.println(124-1)

Hibernate 对于熟悉它的人,是一样非常好的工具,Hibernate 的作者也说过,只要是 Hibernate Team 的人,做出来的系统肯定性能不会差~ 但是不熟悉的人就很难说了~ 我建议使用它的人还是读读它的代码,别盲目使用。很难相象一个程序员,对它的工具做了什么都不知道,还能用好它。

Hibernate 还有一样我最不能接受的,就是它的作者。他根本不能接受别人的意见,只想听奉承。对于别人提出的意见示而不见。最有名的就是在 web 系统里 redeploy 时, Hibernate 会因为内存不能得到释放,引起 web 容器down掉(OutofMemoryExcepiton)。很多人都报告过这个问题,但是开发团队从来不承认这是 Hibernate 引起的。一下说是 commons-log.jar的问题,一下又说是 dom4j的问题,一下又说是 tomcat 的问题(已经证实jboss/weblogic/websphere也会出这问题),一下又说是cglib的问题,呵~ 反正理由多得是~ 就是不关 Hibernate 的问题~ 有人在 JIRA 里开了个BUG,被作者以 Session没有 close 为由给close了,他连测都没测一下~ 我经过测试,证明就算是调用了Session.close还是一样会出现这个问题,只要把Hibernate.jar去掉,一切就可以很好的工作。 Hibernate 的论坛上本来有一个贴子就是说这个问题的,很多人都关注过,但是后来不知道为什么这个贴子不在了。这个问题存在很久了,到最新版的Hibernate也没有解决。我很难理解,JBoss为什么要把它引入到 AS 里面去,它就不怕 Hibernate 引起 redeploy 失效吗?这和JBoss AS的 7*24 不相符啊~


最后我想说,在没有ORM的时候,我们一样能做出系统,而且性能也不差,系统一样可以维护,为什么一定要用ORM?有个朋友说,这些技术只是让程序员舒服了,但是软件不见得就强壮多少。我想这句话很有道理

通篇是你的臆想和猜测
另外,如果你"要不停的在 RDBMS Model 和 POJO 之间转换",说明你还不知道如何用hibernate

帖子里是人家对ORM的一些看法,怎么就成了“臆想和猜测”了?软件设计过程中必然存在审时度势的折衷,走极端往往过犹不及,如果您很会用hibernate,请给兄弟们说说你如何让Hibernate很少在POJO与RDBMS Model之间转换?
0 请登录后投票
   发表时间:2007-01-01  
ahuaxuan 写道
flyspider 写道
ahuaxuan 写道
我觉得楼主应该没有用过hibernate吧,lz并没有写hibernate的优点,而是一个劲的写缺点,ibatis和hibernate其实应该可以看成是互不的两个东西,hibernate学习成本高于ibatis,但是hibernate的效率也高于ibatis,用hibernate也更oo,我看到lz说ibatis更容易优化芸芸,其实一般的系统要优化的sql语句有多少??一般的项目用hibernate是没有问题的,遗留系统或者性能要求非常苛刻的系统应该用ibatis,这两者没有绝对的好和坏的问题,只有不同的系统不同的项目用哪个更合适的问题,如果lz说hibernate不适合你们的系统,那请讲讲理由好吗

hibernate的效率高于iBATIS?请讲讲理由。

1,自动组装对象
2,简化查询(这一点最提高效率)
3,更少的sql
4,更加面向对象
5,学习hibernate对比学习ibatis来说虽然成本高但是收获更加大,因为学习hibernate学习到的其实是一种orm思想,这一点尤其重要,对一个人的发展来说比较有利(这一点扯大了)。
6,对二级缓存良好的支持
7,使多数据库版本的规模不大的产品的实现更加容易

倒,原来是说开发效率。
0 请登录后投票
   发表时间:2007-01-01  
    我hibernate用了2年,使用过程中也碰到过很多乱七八糟的问题,或者解决或者绕过了。
ibatis看了一个晚上,大致了解。
    如果让我在ibatis和hibernate都不熟的基础上对项目的orm框架做选择,我应该
会选择ibatis而不是hibernate。不过在对hibernate比较熟悉的情况下确实是选择hibernate
开发效率会高。
    hibernate是一个重量级的orm框架,其功能的强大使得其灵活性打了一定折扣,可控性也打了一定
折扣。多少显得有点“怪异”的sql重写机制,使得hql的使用受限不少而只能使用native sql。secondary
cache,我看能真正用好的人不多,呵呵。我一贯的做法是自己做cache,而不是用hibernate的cache。

jiming 写道


1. iBatis 易于掌握。拿来文档看半天到两天就可以掌握了。
   Hibernate 可能需要 3 倍以上的时间来掌握。
  
   其中有一些与我探讨的人跟我说 Hibernate 也很容易学,但是在与他们的更深一步的
   讨论中,我发现他们只是使用了 Hibernate 最简单的一部分功能,更深一些的功能,
   和我提出来的一些疑虑他们并没有考虑到。我想绝大部分的人应该都在这个层次内,
   包括我。


  这个是我说会选择ibatis的主要原因,keep it simple stupid,事实上我只需要能满足我自己需求的框架。

jiming 写道


2. iBatis 更容易进行 sql 的 优化。

   这个应该大家都有共识了。另外 Hibernate 生成的 sql 也实在是太难看了。鉴
   于有的朋友提到了 sql 不太重要。我想在这里强调一下我的经验,一般系统性能
   的瓶颈都在数据库上。所以这一点是 iBatis 非常重要的一个优势。

  hibernate生成的sql语句难看点是难看点,人家本来就不是给你看得。如果要做sql的优化,可以用hql或者native sql,这个应该算不上hibernate的缺点了。

jiming 写道

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

   3.1 比如说我有一个表,我需要更新其中的一个字段,iBatis 很简单,执行一个sql
       UPDATE TABLE_A SET column_1=#column_1# WHERE id=#id#
       但是用 Hibernate 的话就比较麻烦了

             这个hibernate可以用bulk update,不会有额外工作两。


jiming 写道

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

            hibernate可以做到,可以把结果直接封装成javabean,map或Object[]等等。
    还是挺优美的。
jiming 写道


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

 

    不需要,见我对3.1的评价。

jiming 写道


4. 开发方面
   4.1 开发效率上,我觉得两者应该差不多
   4.2 可维护性方面,我觉得 iBatis 更好一些。因为 iBatis 的 sql 都保存到
       单独的文件中。而 Hibernate 在有些情况下可能会在 java 代码中保存
       sql/hql。


   开发效率上熟悉hibernate的开发效率肯定会比熟悉ibatis的高,至少很多情况下我都没必要动手写sql代码,呵呵。简单的通过pojo的设计直接生成map文件即可。

   可维护性方面,保存在单独文件和在java代码中保存没有本质区别。对我本人来说,我不喜欢在配置文件中保存这些玩意。


jiming 写道


5. 运行效率
   5.1 在不考虑 cache 的情况下,iBatis 应该会比hibernate 快一些或者很多
      (根据实际情况会有所不同)。


    不管是ibatis还是hibernate归根结底还是对数据库访问。用得好的话,就算不考虑cache hibernate是不会比ibatis慢的。

 
jiming 写道

    
当然 iBatis 也有比较大的缺点
1. 不同数据库类型的支持不好,如果你要开发的系统是要在对中数据间移植,那可能用 hibernate 比较好。
2. 缺省的 cache 支持不好,但是 hibernate 的 cache 支持其实也不是很好,而且很复杂。尤其是对于大并发量的应用。所以我更倾向于自己管理 cache。


    非常感谢这么多朋友对这个话题很感兴趣。但是我感觉大家并没有对我第三部分提到的问题进行更深入的思考。我晚些时候会提交一些 ibatis 的代码。欢迎大家一起来讨论。
  


    我的做法也是自己管理cache。
    其实不管是hibernate还是ibatis,终究只是一个工具,人是不能被工具给约束了的。
    hibernate查询方面提供了多种查询方式,如criteria,hql,native sql,只要灵活应用,基本上能涵括数据库查询的需求了。hibernate在oo方面确实是做得挺好了。同时,在某些时候还可以直接使用jdbc(用spring的话可以使用jdbcTemplate),人对hibernate了解不足而不能灵活使用,不能成为hibernate自身的缺点。当然,学习曲线比较长可以成为其缺点的。呵呵。

0 请登录后投票
   发表时间:2007-01-01  
jiming 写道
3. iBatis 可以进行细粒度的优化

3.1 比如说我有一个表,我需要更新其中的一个字段,iBatis 很简单,执行一个sql
UPDATE TABLE_A SET column_1=#column_1# WHERE id=#id#
但是用 Hibernate 的话就比较麻烦了

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


不说别的,这两个特性hql直接支持,相比而已还多了兼容性,优劣自己判断吧。
0 请登录后投票
论坛首页 入门技术版

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