`
dsotbs936
  • 浏览: 37991 次
  • 性别: 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所需包:hibernate3,依赖包,JDBC

    2. **JPA(Java Persistence API)**: 虽然不是必须,但Hibernate可以作为JPA的实现,因此有时会被一起使用。 3. **CGLIB或ASM**: 用于为那些没有默认构造函数或者不可被代理的类生成动态代理,用于Hibernate的懒...

    kingbaseV8 hibernate jdbc 驱动

    在标题和描述中提到的"kingbaseV8 hibernate jdbc驱动",意味着我们需要关注如何在Hibernate框架中使用KingbaseV8的JDBC驱动进行数据操作。 JDBC(Java Database Connectivity)是Java中用于连接数据库的标准接口,...

    hibernate3_jdbc_spring3_tomcat6(jar包)

    描述 "hibernate3_jdbc_spring3__tomcat6" 提供了简短的项目概述,表明项目主要关注于使用Hibernate 3作为ORM工具,通过JDBC进行数据库交互,Spring 3作为整体框架提供依赖注入和事务管理,而Tomcat 6作为Web应用...

    分别使用Hibernate和JDBC操作数据库

    为了解决这些问题,引入了**Hibernate**,一个强大的对象关系映射(ORM)框架。 **Hibernate** 提供了一种抽象层,将Java对象与数据库表之间的映射自动化,极大地简化了数据库操作。以下是Hibernate的主要知识点: ...

    hibernate + shardingjdbc +springboot 结合做的demo

    在这个示例中,我们将探讨如何将Hibernate ORM框架、ShardingSphere的ShardingJDBC模块与Spring Boot整合,构建一个高效的分布式数据库应用。这样的组合允许我们利用Hibernate的强大ORM能力,同时通过ShardingJDBC...

    Hibernate3框架系列 [ 1 ]

    【标题】:“Hibernate3框架系列 [ 1 ]” 在这一系列的文章中,我们将深入探讨Java领域中的著名对象关系映射(ORM)框架——Hibernate3。ORM框架的主要目标是通过提供一种编程模型,使得开发人员可以使用面向对象的...

    JDBC与Hibernate区别

    然而,由于其内部的映射和对象创建过程,对于大量数据操作,Hibernate可能会比JDBC慢一些,尤其是在使用Iterator遍历大数据集时。 在性能方面,JDBC通常在数据读写速度上占有优势,特别是当使用批处理时。而...

    搭建hibernate所使用的jar包,内含mysql的jdbc的jar包

    标题提到的是“搭建hibernate所使用的jar包,内含mysql的jdbc的jar包”,这表明这个压缩包包含了用于构建Hibernate框架的库文件,并且这些库中还包括了连接MySQL数据库的Java Database Connectivity (JDBC)驱动。...

    Hibernate and JDBC

    - **灵活性限制**:相比直接使用JDBC,Hibernate在某些场景下可能缺乏足够的灵活性,特别是对于需要高度定制化的查询。 - **资源消耗**:Hibernate需要额外的内存来存储Session对象,对于大规模部署的应用程序来说,...

    springmvc+hibernate+oracle基础框架

    通过使用Hibernate,开发者可以避免编写大量的JDBC代码,而是用面向对象的方式来操作数据库。Hibernate支持实体类与数据库表之间的映射,提供CRUD操作的API,以及事务管理和缓存机制。在SpringMVC中,Hibernate可以...

    struts+hibernate+jdbc双表查询

    在实际项目中,"UserDaoImpl.java"可能是用户数据访问层的实现类,它可能包含使用Hibernate或JDBC进行双表查询的方法。例如,该类可能会有如下方法: ```java public List&lt;User&gt; getUsersWithOrders() { // ...

    本人理解hibernate 与 JDBC 的最本质区别

    Hibernate 是一个对象关系映射(ORM)框架,而 JDBC(Java Database Connectivity)是 Java 语言中用于与数据库交互的标准 API。两者的本质区别主要体现在以下几个方面: 1. **编程模型**: - **JDBC**:使用 ...

    jdbc和hibernate的区别

    3. ORM框架(如Hibernate)的性能通常不会超过JDBC,但它们提供了更高层次的抽象和便利,简化了数据库操作。 4. 对于创建和更新操作,如果使用了Hibernate的批处理功能,其性能可能优于未使用批处理的JDBC。 5. ...

    自己动手模仿Hibernate写数据库框架

    3. **JDBC基础**:尽管我们要模仿Hibernate,但JDBC(Java Database Connectivity)仍然是与数据库交互的基础。我们需要理解JDBC的连接、查询、结果集处理等流程,以便在我们的框架中实现这些功能。 4. **配置文件...

    Spring对Hibernate及JDBC提供的支持

    在实际项目中,Spring还允许开发者结合使用Hibernate和JDBC。例如,在大数据量的简单查询场景下,可以选择性能较高的JDBC;而在复杂的对象关系映射或者更新操作时,可以利用Hibernate的ORM优势。Spring的这种灵活性...

    Struts Hibernate Spring 三个框架简介

    Hibernate是一个强大的ORM框架,它消除了传统JDBC操作数据库的繁琐。主要特点包括: 1. **对象持久化**:Hibernate允许开发者将Java对象直接映射到数据库表,无需关心SQL的编写,提高了开发效率。 2. **映射文件**...

    struts2.16 spring2.56 hibernate3.2 sqljdbc4 完整jar包

    Struts2.16、Spring2.5.6、Hibernate3.2以及sqljdbc4是四个在Java开发中广泛使用的开源框架和数据库驱动,它们在构建企业级Web应用程序时起着至关重要的作用。 Struts2.16是MVC(模型-视图-控制器)设计模式的一个...

    oracle分别使用jdbc和hibernate的例子

    本文将深入探讨如何使用JDBC和Hibernate来操作Oracle数据库,同时结合提供的标签"源码"和"工具",我们将讨论它们的实现细节和优势。 首先,JDBC是Java语言的标准API,它允许Java应用程序与各种类型的数据库进行通信...

    Jdbc 和hibernate

    标题 "Jdbc 和hibernate" 提到的两个主要概念是Java数据库连接(JDBC)和Hibernate,它们都是Java开发中用于与关系型数据库交互的重要技术。本文将深入探讨这两个技术,以及它们之间的区别和联系。 JDBC是Java平台...

    spring,spring mvc,hibernate,ehcache JavaWeb后台框架

    3. **Hibernate**:Hibernate是一个强大的对象关系映射(ORM)框架,它简化了Java应用与数据库之间的交互。通过Hibernate,开发者可以使用Java对象而不是SQL语句来操作数据库。它提供了查询语言HQL和 Criteria API,...

Global site tag (gtag.js) - Google Analytics