赛迪网 > IT技术 Java > (最新更新)Java基础
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

Hibernate与JDO肩并肩

发布时间:2006.03.10 06:23     来源:http://chris-richardson.blog-city.com/    作者:

在theServerSide.com上有一些人声称JDO的开发人员已经把JDO带向错误的道路,并且指出Hibernate相对更优秀。然而,根据我的经验Hibernate和JDO都是O/R Mapping的优秀技术。

它们有许多共同的特征,包括:

  • 支持Plain Old Java Object (POJO) 的几近透明的持久层

  • 基於XML的object/relational映射

  • 两者都有一个"EntityManager" API - Hibernate Session 和 JDO PersistenceManager

  • 都可以在或不在Container中运行应用程序

  • 事务级和应用级的cache

  • 丰富的查询语言 (query language)

  • 能够积极和消极两种方式装载有关联的对象

  • 有效率地处理大数据集合

因此,JDO 和 Hibernate 两种版本的同一应用程序经常很相似。

关于如何装载对象和执行查询,我们来看看下面的例子。这里有两个版本的RestaurantRepository类,一个是JDO的,另一个是Hibernate的。 RestaurantRepository类定义了寻找饭店的方法:

  • findRestaurant() - 找单一饭店 (类似于 findByPrimaryKey()).

  • findAvailableRestaurants() - 执行查询,找到在特定时间特定区域营业的饭店

列表 1 显示了JDO版的 RestaurantRepository 类, 列表 2 显示了Hibernate 的版本。

列表 1 - JDO 版

public class JDORestaurantRepositoryImpl
    implements RestaurantRepositoryImpl {

  public Restaurant findRestaurant(String restaurantId) {
   PersistenceManager pm = PMRegistry.getPM();
   return (Restaurant) pm.getObjectById(
    pm.newObjectIdInstance(
     JDORestaurant.class,
     restaurantId),
    true);
  }


    private static final String QUERY_STRING =
        "serviceArea.contains(zipCode) && timeRanges.contains(tr) && "
            + "(tr.dayOfWeek == day && "
            + "(tr.openHour < hour || (tr.openHour == hour && tr.openMinute <= minute)) && "
            + "(tr.closeHour > hour || (tr.closeHour == hour && tr.closeMinute > minute)))";

    public Collection findRestaurants(
        Address deliveryAddress,
        Date deliveryTime) {
        Calendar c = Calendar.getInstance();
        c.setTime(deliveryTime);
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        PersistenceManager pm = PMRegistry.getPM();
        Query query = pm.newQuery(JDORestaurant.class, QUERY_STRING);
        query.declareVariables("JDOTimeRange tr");
        query.declareParameters(
            "String zipCode, int day, int hour, int minute");
        Collection result =
            (Collection) query.executeWithArray(
                new Object[] {
                    deliveryAddress.getZip(),
                    new Integer(dayOfWeek),
                    new Integer(hour),
                    new Integer(minute)});
        return result;
    }
}

 

列表 2 - Hibernate 版

public class HibernateRestaurantRepositoryImpl
    implements RestaurantRepositoryImpl {

    public Restaurant findRestaurant(String restaurantId) {
        try {
            Session session = HibernateSessionRegistry.getSession();
            Restaurant restaurant =
                (Restaurant) session.load(
                    HibernateRestaurant.class,
                    new Long(restaurantId));
            return restaurant;
        } catch (HibernateException e) {
            throw new ApplicationRuntimeException(e);
        }
    }

    public Collection findRestaurants(
        Address deliveryAddress,
        Date deliveryTime) {
        try {
            Query query =
                makeFindRestaurantsQuery(
                    deliveryAddress,
                    deliveryTime);
            return query.list();
        } catch (HibernateException e) {
            throw new ApplicationRuntimeException(e);
        }
    }

    private Query makeFindRestaurantsQuery(
        Address deliveryAddress,
        Date deliveryTime)
        throws HibernateException {
        Calendar c = Calendar.getInstance();
        c.setTime(deliveryTime);
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        Session session = HibernateSessionRegistry.getSession();
        Query query =
            session.getNamedQuery("findAvailableRestaurants");
        query.setString("zipCode", deliveryAddress.getZip());
        query.setInteger("dayOfWeek", dayOfWeek);
        query.setInteger("hour", hour);
        query.setInteger("minute", minute);
        query.setCacheable(true);
        return query;
    }
}

每个 repository 由两个方法组成。这两个方法调用相应的 persistence framework API:

  • findRestaurant() - JDO 版调用 PersistenceManager.getObjectById() 而 Hibernate版调用 Session.load()

  • findAvailableRestaurants() - 两个版本都使用Query interface来执行有名参数的查询. 有个不同的地方,Hibernate 版用 named query, named query会在一个映射文件中定义,而 JDO 版用镶嵌在类里的 query 

两个类通过 ThreadLocal-based registry 得到 Hibernate Session 和 JDO PersistenceManager。如你所见,除了方法和类的名字不同,其它code都非常相似。

 

 


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· Java 2 图形设计卷II——第2章 applet和应用 (09-20) · XML处理 (05-04)
· J2EE应用程序部署的一些建议(3) (09-25) · Eclipse插件开发系列(0):Java Applicatio (09-17)
· java.util.regex.Pattern (03-09) · 一个检查邮件地址有效性的正则表达式程序 (07-27)
· java异常机制分析 (08-26) · 人类原始语言-面向对象语言 (10-11)
· 毫无废话: 从0开始一点一滴用java开发自己的B (05-16) · 毫无废话: 从0开始一点一滴用java开发自己的B (12-21)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
· 电子商务盈利新招:垂直化渠道管理新趋势
· 互联网加速蜕变 运营商进军搅动市场格局
· 08 IT技术风起云涌 专访 ITIL落地难在哪
· 视频加密保护解决方案 文档安全解决方案
  IT博客 ·曾剑秋·项立刚·Java学习·网管
  IT技术论坛 ·开发·网管·安全·数据库·系统