`
dsotbs936
  • 浏览: 37090 次
  • 性别: Icon_minigender_1
  • 来自: 浙江
文章分类
社区版块
存档分类
最新评论

使用Hibernate3作为JDBC框架

阅读更多
发布时间:2006.03.10 04:27     来源:CSDN    作者:

 

 

There's been a certain amount of noise recently surrounding simple JDBC frameworks like iBATIS. I've liked the idea of iBATIS myself, for use in applications which don't need an object-oriented domain model, and don't work with deep graphs of associated entities in a single transaction. A JDBC framework also makes good sense if you are working with some kind of "insane" legacy database; ORM solutions tend to assume that associations are represented as nice clean foreign keys with proper referential integrity constraints (Hibernate3 much less so than Hibernate 2.x).

 

Some people even suggest that JDBC frameworks are a suitable alternative to ORM, even for those systems to which ORM is best suited: object-oriented applications with clean relational schemas. They argue that you are always better off with hand-written SQL than generated SQL. Well, I don't think this is true, not only because the overwhelming bulk of SQL code needed by most applications is of the tedious kind, and simply does not require human intervention, but also because a JDBC framework operates at a different semantic level to ORM. A solution like iBATIS knows a lot less about the semantics of the SQL it is issuing, and of the resulting datasets. This means that there is much less opportunity for performance optimizations such as effficent caching. (By "efficient", I am referring mainly to efficient cache invalidation strategies, which are crucial to the usefulness of the cache.) Furthermore, whenever we have seen handwritten SQL, we have seen N+1 selects problems. It is extremely tedious to write a new SQL query for each combination of associations I might need to fetch together. HQL helps significantly here, since HQL is much less verbose than SQL. For a JDBC framework to be able to make the kind of optimizations that an ORM can make, it would have to evolve to a similar level of sophistication. Essentially, it would need to become an ORM, minus SQL generation. In fact, we already start to see this evolution taking place in existing JDBC frameworks. This begins to erode one of the stated benefits: the claimed simplicity.

 

It also raises the following interesting thought: if, by gradually adding stuff, a JDBC framework will eventually end up as ORM, minus SQL generation, why not just take an existing ORM solution like, ooh, um ... Hibernate, maybe ... and subtract the SQL generation?

 

The Hibernate team has long recognized the need to mix and match generated SQL with the occasional handwritten query. In older versions of Hibernate, our solution was simply to expose the JDBC connection Hibernate is using, so you can execute your own prepared statement. This started to change a while ago, and Max Andersen has recently done a lot of work on this. Now, in Hibernate3, it is possible to write an entire application with no generated SQL, while still taking advantage of all of Hibernate's other features.

 

Do we really expect or intend people to use Hibernate in this way? Well, not really - I doubt there are many people out there who really enjoy writing tedious INSERT, UPDATE, DELETE statements all day. On the other hand, we do think that quite a few people need to customize the occasional query. But to prove a point, I'll show you how you can do it, if you really want to.

 

Let's take a simple Person-Employment-Organization domain model. (You can find the code in the org.hibernate.test.sql package, so I'm not going to reproduce it here.) The simplest class is Person; here's the mapping:

<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>

 

 

The first thing to notice is the handwritten INSERT, UPDATE and DELETE statements. The ? order of the parameters matches to the order in which properties are listed above (we'll have to eventually support named parameters, I suppose). I guess there is nothing especially interesting there.

 

More interesting is the <loader> tag: it defines a reference to a named query which is to be used anytime we load a person using get(), load(), or lazy association fetching. In particular, the named query might be a native SQL query, which it is, in this case:

<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>

 

 

(A native SQL query may return multiple "columns" of entities; this is the simplest case, where just one entity is returned.)

 

Employment is a bit more complex, in particular, not all properties are included in the INSERT and UPDATE statements:

<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>

 

<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>

 

 

The mapping for Organization has a collection of Employments:

<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"/> <!-- only needed for DDL generation -->

 

<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>

 

 

Not only is there a <loader> query for Organization, but also for its collection of Employments:

<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>

 

 

When I was writing this code, I really started to feel the advantages of having Hibernate write the SQL for me. In just this simple example, I would have eliminated more than 35 lines of code that I would have to later maintain.

 

Finally, for ad hoc querying, we can use a native SQL query (a named query, or one embedded in the Java code). For example:

<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>

 

 

Personally, I prefer to program in Java than in XML, so all this stuff is much too XML-heavy for my liking. I think I'll stick with SQL generation, wherever I can, which is almost everywhere. It's not that I don't like SQL. In fact, I am a great fan of SQL, and just love watching the queries scroll past when I turn Hibernate's logging on. It's just that Hibernate is much better at writing SQL than I am.

 

About the author

 

Gavin King (gavin@hibernate.org)
Blog: http://blog.hibernate.org/

Gavin King is the founder of the Hibernate project. He is co-author of the book Hibernate in Action, to be published by Manning Publications. He is currently involved in the JDO expert group and is employed by JBoss Inc, where he is redesigning the JBoss CMP engine.

分享到:
评论

相关推荐

    hibernate资源框架

    它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate...

    springmvc_hibernate_ibatis_jdbc

    整合了springmvc,hibernate,ibatis,jdbc等技术的强大框架,写的非常全面,谢谢老邵的成果。

    hibernate3所需JAR包

    hibernate3是目前比较稳定的一款持久层框架,该资源包括有hibernate3核心包、hibernate3依赖包、JDBC持久层驱动

    hibernate3源码

    Hibernate是一种Java语言下的对象...Hibernate不仅负责从Java类到数据库表的映射(还包括从Java数据类型到SQL数据类型的映射),还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL和JDBC上的开发时间。

    hibernate+junit+mysql-jdbc开发核心jar包三合一

    ssh框架,javaweb开发,jar包。hibernate+junit+mysql-jdbc;

    Apache Dbutils JDBC 框架demo代码

    commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司...

    spring+springMVC+mybatis+struts2+jdbc+hibernate(全面集成,如果工作框架中请勿这种集成)

    spring+springMVC+mybatis+struts2+jdbc+hibernate 全面集成 此框架本人花费2天时间完成 工作中请勿配置如此多元化框架 框架的意义是为了让代码风格统一 此框架是为了学习 作为参考 jdbc.properties为数据库链接参数...

    hibernate框架的环境搭建

    hibernate框架的环境搭建,Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架

    spring+struts2+hibernate框架说明

    在SSH 的组合框架模式中,三者各自的作用。Struts 是一个很好的MVC框架,主要技术是Servlet和Jsp。Struts的MVC设计模式可以使我们的...Hibernate对JDBC进行了非常轻量级的封装,它使得与关系型数据库打交道变得非常轻松

    spring3+struts2.2+hibernate3框架包

    正在使用的java web项目中的SSH框架包,这些包没有冲突,是基于spring3+struts2.2+hibernate3的,还有jdbc驱动、mysql连接驱动jdbc包、mail包、dwr包、upload.jar包等。

    hibernate-prj1

    3、Hibernate 框架主要包括持久化对象(PersistentObjects)、Hibernate 配置文件 (一般被命名为*.cfg.xml)、Hibernate 映射文件(一般被命名为*.hbm.xml) 三部分; 4、编译运行基于 Hibernate 框架的工程,需要...

    学习笔记,hibernate框架入门

    它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate...

    Struts2+Spring3+Hibernate3 用户管理系统实例源码

    本例主要是实现了struts2+spring3+hibernate3的 基本框架搭建的注册登录,以及用户增删改查,适于初学者学习。 包括:注册 登录功能 分页的实现 前端校验 验证码的实现 注册时有ajax 校验,登录时 后台从数据库...

    Hibernate实践例子程序

    Hibernate 是一个开源的O/R mappimg的框架,基于JDBC提供了一种持久性数据管理的方案,相对于EntityBean来说是相当轻量级的。由于Hibernate是基于 JDBC的,所以它的数据库查寻的能力相对于CMP来说也是异常强大的,...

    hibernate框架

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装, 使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端...

    hibernate框架4.3.5.

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端...

    基于SpringJDBC的轻量级ORM框架sborm.zip

    平时不太喜欢使用hibernate和mybatis,主要是使用spring jdbc,写这个东西的出发点主要是平时使用spring jdbc觉 得比较麻烦,重复性的代码偏多,一方面通过自动mapper降低返回结果处理工作量,另一方面参考...

    Hibernate数据持久层框架是一种Java语言下的对象关系映射解决方案.rar

    Hibernate 是一种Java语言下的...Hibernate不仅负责从Java类到数据库表的映射(还包括从Java数据类型到SQL数据类型的映射),还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL和JDBC上的开发时间。

    Java框架hibernate基础教程,简单上手。

    它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate...

    easydao:简单易用的DAO框架,非侵入式的api,可以与Hibernate、SpringJdbc等框架很好的集成

    easydaoEasydao是简单易用的轻量级DAO(Data Access Object)框架,它集成了Hibernate实体维护和Mybaits SQL分离的两大优势,提供了非入侵式API,可以与Hibernate、SpringJdbc等数据库框架很好的集成。### Author:...

Global site tag (gtag.js) - Google Analytics