网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  hibernate3.x:最出色的orm框架     
  文章作者:未知  文章来源:水木森林  
  查看:142次  录入:管理员--2007-11-17  
 
一、前言
         
jdbc是java操作数据库最常用的数据库接口,它隔离了数据库的复杂度,使程序员可以将主要精力放到程序逻辑上来。
而jdbc也只是提供了和数据库交互的简单方式,如打开数据库表,执行sql语句等。这对于复杂的程序也需要编写大量的代码,因此,近几年在java数据库领域出现了许多框架,这此框架重新对jdbc进行了更高层次的封装。如早期的ibatis。这个框架使用起来非常方便。它也没有基于复杂的面向对象模型。也不工作在复杂的关系图中。这种最初级的框架将数据库和应用程序隔离开来。使程序员只操作逻辑数据库。但由于这种框架不是基本面向对象和关系模型,在对付大规模应用程序时仍然捉襟见肘。基于这些不足,最近许多基于关系映射(orm)的数据库框架开始流行起来。hibernate就是其中的佼佼者。orm的基本思想是使用外键和适当的约束将抽象不同的数据库。在最新的hibernate3.x中,增强了对约束的控制,使用功能更强,也更容易使用。
 
在这些orm框架刚兴起的时候,有很多人认为orm框架最多只是从多选择之一。即使某个orm框架做的非常出钯,将对象和数据库之间映射的非常完美也是如此。他们认为直接使用sql写程序才是王道,而使用自动生成的sql的效率低下,而且很不灵活。但随着程序规模越来越大,这种想法越来越站不住脚。这主要并不只是因为直接使用sql将产生大量的代码,而是因为使用orm框架,我们将操作一个完全不同的层:orm层。直接使用sql也可能产生其他的问题,如我们经常会遇到的n+1选择问题。而且在连接很多表时,我们会一遍一遍地重复写非常类似的sql语句。如果我们使用hibernate,这些问量就将荡然无存。我们可以使非常简单的hql来完成上述复杂的问题。象hibernate一样orm框架还应该能进行各种优化,以使操作达到最佳化。就目前来看,这些框架的优化功能已经越来越强,正在逐步取代用jdbc和sql操作数据库的方式。
 
    虽然可以用orm框架来编写大多数程序,但有时也需要直接使用sql来操作。也许hibernate的开发团队也意识到了这一点,也为hibernate提供了直接执行sql的功能。在早期的hibernate版本中,解决方案是直接将jdbc连接暴露给用户,这样程序员就可以直接使用prepared statment来执行sql了。但在新的hibernate3.x中,这种情况已经被改变了。现在,hibernate3.x可以不使用一条sql编写整个应用程序,而且这并不会影响hibernate的灵活性,同时也可以使用hibernate的所有其他特性。

二、hibernate3.x功能演示

    上面说了很多hibernate的好处,也面就让我们来体会一下hibernate3.x在这方面的卓越表现。我们将使用一个简单的person-employment-oranization模型来说明。最简单的类是person,下面是它的定义:

<class name="person" lazy="true">
    <id name="id" unsaved-value="0">
        <generator class="increment"/>
    </id>
    <property name="name" not-null="true"/>
 
    <loader query-ref="person"/>
 
    <sql-insert>insert into person (name, id) values ( upper(?), ? )</sql-insert>
    <sql-update>update person set name=upper(?) where id=?</sql-update>
    <sql-delete>delete from person where id=?</sql-delete>
</class>
 
    看了上面的定义,可能我们会首先注意到三个手写的sql语句:insert、update和delete。其中的?将匹配上面所列的两个属性(这两个属性是id和name)。除了这个,这三条语句没有什么之处。
 
    也许很多读者最感兴趣的是<loader>标签。这个标签定义了一个命名查询。这个查询在任何时候当我们使用get(),load()装载person或使用惰性关联获取数据时都会执行它。一般来讲,这个命名查询应该是一个sql语句,如下面如示:

<sql-query name="person">
    <return alias="p" class="person" lock-mode="upgrade"/>
    select name as {p.name}, id as {p.id} from person where id=? for update
</sql-query>
 
    注:一个本地的sql查询可能会返回多个"实体列",但本例比较简单,只返回了一个实体。
    employment相对更复杂一点,而且并不是所有的属性都包括在insert和update中。定义如下:

<class name="employment" lazy="true">
    <id name="id" unsaved-value="0">
        <generator class="increment"/>
    </id>
 
    <many-to-one name="employee" not-null="true" update="false"/>
    <many-to-one name="employer" not-null="true" update="false"/>
    <property name="startdate" not-null="true" update="false"
        insert="false"/>
    <property name="enddate" insert="false"/>
    <property name="regioncode" update="false"/>
 
    <loader query-ref="employment"/>
 
    <sql-insert>
        insert into employment
            (employee, employer, startdate, regioncode, id)
            values (?, ?, current_date, upper(?), ?)
    </sql-insert>
    <sql-update>update employment set enddate=? where id=?</sql-update>
    <sql-delete>delete from employment where id=?</sql-delete>
</class>
 
下面是命名查询employment的定义:
 
<sql-query name="employment">
    <return alias="emp" class="employment"/>
    select employee as {emp.employee}, employer as {emp.employer},
        startdate as {emp.startdate}, enddate as {emp.enddate},
        regioncode as {emp.regioncode}, id as {emp.id}
    from employment
    where id = ?
</sql-query>
 
    下面的organization的定义:

<class name="organization" lazy="true">
    <id name="id" unsaved-value="0">
        <generator class="increment"/>
    </id>
 
    <property name="name" not-null="true"/>
 
    <set name="employments"
        lazy="true"
        inverse="true">
 
        <key column="employer"/>
 
        <one-to-many class="employment"/>
 
        <loader query-ref="organizationemployments"/>
    </set>
 
    <loader query-ref="organization"/>
 
    <sql-insert>
        insert into organization (name, id) values ( upper(?), ? )
    </sql-insert>
    <sql-update>update organization set name=upper(?) where id=?</sql-update>
    <sql-delete>delete from organization where id=?</sql-delete>
</class>
 
    下面是两个命名查询的定义:

<sql-query name="organization">
    <return alias="org" class="organization"/>
    select name as {org.name}, id as {org.id} from organization
    where id=?
</sql-query>
 
 
<sql-query name="organizationemployments">
    <return alias="empcol" collection="organization.employments"/>
    <return alias="emp" class="employment"/>
    select {empcol.*},
        employer as {emp.employer}, employee as {emp.employee},
        startdate as {emp.startdate}, enddate as {emp.enddate},
        regioncode as {emp.regioncode}, id as {emp.id}
    from employment empcol
    where employer = :id and deleted_datetime is null
</sql-query>
 
    当我们看到这时,可能已经感觉到hibernate的好处,那就是至少我们可以少维护数十行的java代码。而且将这些代码转换成了xml配置文件,这样将使程序更加灵活和可维护。
 
    下面的代码是我们的最后的工作,一个命名查询allorganizationswithemployees的定义:

<sql-query name="allorganizationswithemployees">
    <return alias="org" class="organization"/>
    select distinct name as {org.name}, id as {org.id}
    from organization org
    inner join employment e on e.employer = org.id
</sql-query>
 
 
    虽然在现在为止还是有很多人喜欢直接使用sql,这也包括我在内。但使用以hbiernate为首的orm框架可能会给我们带来更多的好处,如它自动产生的sql一般会比我们手写的更优化。因此,hibernate将成为软件大工业时代的新的操作数据库的标准。
 
 
上一篇: hibernate:利用配置文件编写程序生成数据库    下一篇: hibernate参数说明
  相关文档
技巧:java垃圾收集器使用小诀窍 11-16
用java制作网络文件下载系统 11-17
java进阶:减少对象的创建提高java性能 11-16
使用sax和xslt实现复杂数据转换(组图) 11-17
java知识:关于string和stringbuffer 11-17
javaweb服务学习报告—web简介 11-17
java网络五子棋的源代码 11-17
实现j2ee中的多字节字符处理(组图) 11-17
freemarker设计指南(3) 11-17
深入探讨 spring 与 struts 的集成方案 11-16
运用jakarta struts的七大实战心法(1) 11-16
认识jini 11-17
scjp认证套题解析之七 11-16
java实现类msn、qq好友上线通知界面 11-16
java程序员需要了解的几个开源协议 11-17
针对 .net 开发人员的存储过程评估 11-17
weblogic8中文显示乱码解决办法 11-17
j2me入门:建立一个midlets应用程序(图) 11-17
java新手解惑(转) 11-17
aop和spring事务处理 11-16
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息