Hibernate 是流行的处理对象/关系持久化及查询的开源工具。 在Hibernate 中,数据库表与POJO(“plain old Java objects”,“普通Java对象”)类之间的映射是由一组XML 映射文件来配置的。 hbm2java 是把映射文件转化成POJO 类的代码生成器。它是Hibernate Tools 子项目的一部分, 可以从独立的Hibernate Extension下载包中得到。
版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接作者:John;Smart;
czyczy(作者的blog:
http://blog.matrix.org.cn/page/czyczy)
原文:
http://www.onjava.com/pub/a/onjava/2005/12/14/hibernate-class-generation-with-hbm2java.html译文:
http://www.matrix.org.cn/resource/article/44/44248_hbm2java+Hibernate.html关键字:hbm2java;Hibernate
对于管理Hiberante 映射文件,现有多种策略, 如:
· 一切手工编写
· 把xdoclet标记放在你的Java 类中, 让其生成相应的映射文件。
· 从SQL 模式(schema)生成Hibernate 映射文件和Java类。
· 手工编写Hibernate 映射文件, 并且从Hibernate 映射生成Java类和SQL模式。
· 基于给定的SQL 模式,手工编写Hibernate 映射文件,并利用hbm2java工具生成Java类。
在本文中, 我们会着眼于上述方法中的最后那种方法。尽管这样的选择通常只是约略的尝试, 但此方法的确在多数情况下有许多优势:
· Hibernate 映射集中在映射文件中,而不是把这些信息散布在Java源代码中,这使维护变得更加容易。在某些情况下,XDoclet annotation 不支持所有在Hibernate映射模式中可用的功能,你还可通过映射获得更好的控制。
· 数据库模式可分开来维护,而不是从Java 类或Hibernate映射文件生成。这允许那些对Java/Hibernate不甚了解的数据库管理员(DBA)对数据库细节(索引,表空间,表类型等)本身有更好的控制。
由映射文件生成Java类这种方式下,Hibernate映射文件主导着一切。所有的映射信息都集中在这些文件中, 就意味着不会在源代码中使用annotations。所有的持久化类都由hbm2java工具生成。之后,那些类就不能被修改。
此过程如图1所示。首先,你持有一组Hibernate映射文件。你或许也需要一个hbm2java配置文件,通常称之为hbm2java.xml。利用这两个引子,hbm2java工具为每个Hibernate映射文件生成一个或多个Java类。hbm2java配置文件对类生成过程的优化是有用的。
图1.用hbm2java工具将Hibernate映射生成Java类
一个简单类生成的例子让我们从一个非常简单的例子开始。假设我们想映射一个BOOK的简单数据库表,表结构定义如下:
Column | Type | Modifiers
------------+-----------------------+-----------
BOOK_ID | character(32) | not null
BOOK_TITLE | character varying(80) | not null
BOOK_ISBN | character varying(20) | not null为了生成这个类, 我们可以使用以下的Hiberante映射文件。注意怎样利用元属性(meta-attriute)来添加注释或优化类的生成。
<?xml version="1.0"?>
<hibernate-mapping>
<class name="Book" table="BOOK">
<meta attribute="class-description">
A Book business object.
@author Duke
</meta>
<id name="id" type="string" unsaved-value="null" >
<column name="BOOK_ID" sql-type="char(32)" not-null="true"/>
<generator class="uuid.hex"/>
</id>
<property column="BOOK_NAME" name="name"/>
<property column="BOOK_ISBN" name="isbn">
<meta attribute="field-description"/>
The unique ISBN code for this book.
</meta>
</property>
</class>
</hibernate-mapping>
使用此映射文件,hbm2java会生成看起来象这样的类:
/**
* A Book business object.
* @author Duke
*/
public class Book {
private String id;
private String name;
private String isbn;
public Book() {
}
public String getId() {
return id;
}
private void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* The unique ISBN code for this book.
*/
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
}
为实际项目生成类实际上,hbm2java被设计成用来把Hibernate映射文件转化成一组相应的Java类。如果你想在实际的应用程序中使用这种方法,很显然,对于所有的Hibernate映射文件一次性生成类会更为方便。最好的方法是把类生成结合进你的自动化构建过程中。
结合进Ant构建过程中使用Ant调用hbm2java是相当直接的。首先,你需要申明hbm2java任务(task)以便Ant可以调用它:
<taskdef name="hbm2java"
classname="net.sf.hibernate.tool.hbm2java.Hbm2JavaTask"
classpathref="project.class.path"/>
接着,你要用到这个任务。例如,通过写一个目标(target)将源目录中的所有*.hbm.xml文件生成源代码。假设${src.hibernate}表示含有Hibernate映射文件的目录,${src.generated}就是你想放源代码的地方。这样Ant任务看起来就象是:
<target name="codegen"
description="Generate Java source code
from the Hibernate mapping files">
<hbm2java output="${source.generated}">
<fileset dir="${src.hibernate}">
<include name="**/*.hbm.xml"/>
</fileset>
</hbm2java>
</target>
用Maven 1 定制构建过程为结合进Maven ( 1.0)构建过程,你需要修改maven.xml文件。Maven代码就存放在这个文件中。脚本(script)主要检查了Hibernate映射文件自上次类生成后是否已被更改(使用uptodate 标记),如果没有,就调用此前所描述的Ant中的hbm2java任务。这种情况下,我们做了以下的假设:
· hbm2java.xml配置文件应在src/hibernate目录中
· Hibernate映射文件应在src/hibernate目录中
· 在src/generated/src/java目录下生成Java类
<goal name="generate-hibernate-classes">
<ant:echo message="Hibernate class generation"/>
<fileset dir="${basedir}/src" id="fileset.hbm.xml">
<include name="**/*.hbm.xml"/>
</fileset>
<uptodate property="hibernateBuild.uptodate"
targetfile="${maven.src.dir}/generated/hbm.jar">
<srcfiles refid="fileset.hbm.xml"/>
</uptodate>
<j:set var="buildHibernateFiles"
value="${hibernateBuild.uptodate}"/>
<j:choose>
<j:when test="${buildHibernateFiles != null}">
<ant:echo message="Hibernate classes up to date"/>
</j:when>
<j:otherwise>
<ant:echo message="Generating Hibernate classes to src/java"/>
<ant:taskdef name="hbm2java"
classname="net.sf.hibernate.tool.hbm2java.Hbm2JavaTask"
classpathref="maven.dependency.classpath"/>
<ant:hbm2java config="${maven.src.dir}/conf/hbm2java.xml"
output="${maven.src.dir}/generated/src/java" >
<ant:fileset dir="${maven.src.dir}/hibernate">
<ant:include name="**/*.hbm.xml"/>
</ant:fileset>
</ant:hbm2java>
<ant:jar jarfile="${maven.src.dir}/generated/hbm.jar">
<fileset refid="fileset.hbm.xml"/>
</ant:jar>
</j:otherwise>
</j:choose>
</goal>
用Maven 2 定制构建过程若碰巧你正使用Maven 2,事情就更简单一点了。把maven-antrun-plugin插件添加到pom.xml文件中,而不是在maven.xml文件中使用完整的goals属性(pre and post goals)。在此插件中的task那部分,你可以象上述那样直接调用Ant 任务。
<project...>
<modelVersion>4.0.0</modelVersion>
...
<build>
...
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="maven.dependency.classpath"/>
<hbm2java output="src/generated">
<fileset dir="src/hibernate">
<include name="**/*.hbm.xml"/>
</fileset>
</hbm2java>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
在Hibernate 3中使用hbm2javaHbm2java 工具已经经受了Hibernate 3 的考验。hbm2java任务与其它相似的任务一起,被集成进了新版Hibernate 工具集中的hibernatetool任务(撰写此文时仍是alpha版)。Ant任务需要在类路径(class path)中查找以下的.jar 文件:
· hibernate-tools.jar
· velocity-1.4.jar
· velocity-tools-generic-1.4.jar
· jtidy-r8-21122004.jar
· hibernate3.jar
· JDBC drivers
这样一来,Ant任务就要作如下申明:
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="maven.dependency.classpath"/>
最后,你在hibernatetool 任务中调用hbm2java任务,做法如下:
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="maven.dependency.classpath"/>
<hibernatetool destdir="src/main/generated/src/java">
<configuration configurationfile="src/main/hibernate/hibernate.cfg.xml">
<fileset dir="src/main/hibernate">
<include name="**/*.hbm.xml"/>
</fileset>
</configuration>
<hbm2java />
</hibernatetool>
注意:尽管Hibernate 3版的工具是很有前途的,但它仍只是在alpha阶段,因此使用时务必小心为是。(译注:翻译此文时最新的Hibernate版本是3.1.2,Hibernate Tools的版本是3.1 beta 4)
定制生成的Domain类现在你知道了怎样从Hibernate映射生成Java源代码, 那么下一步呢?
为了更加具体地讨论,我们将使用如图2 和3所描述的简单类模型。这个类模型表示Employee数据库。每个employee赋予一country,讲一种或多种language。每个country 也有一组国际机场(airport)。
图2. 示例应用程序的UML类图
图3. 示例中所用的数据库模式
有时,你可能想添加域逻辑到Domain类中。实际上,对多数人来说,生成Java类的主要缺点是Domain类变得相对被动,而且把业务逻辑方法加入生成的Domain类中并不容易,就如所论证的那样使它们更不接近“面向对象“。对这问题并没有一个万能的解决方案,但我们在此描述了一些可能的方法。
把代码放入映射文件: class-code元属性(meta attribute)对于简单的方法,你可以用class-code元属性来在Hibernate映射文件中指定额外的Java代码。例如,假设我们想在country和airports间建立双向关系。只要我们想增加airport属性到Country 对象,我们就要确定在Airport对象中相应地增加country属性。我们可以这么做:
<class name="Country" table="COUNTRY" dynamic-update="true">
<meta attribute="implement-equals">true</meta>
<meta attribute="class-code">
<![CDATA[
/**
* Add an airport to this country
*/
public void addAirport(Airport airport) {
airport.setCountry(this);
if (airports == null) {
airports = new java.util.HashSet();
}
airports.add(airport);
}
]]>
</meta>
<id name="id" type="long" unsaved-value="null" >
<column name="cn_id" not-null="true"/>
<generator class="increment"/>
</id>
<property column="cn_code" name="code" type="string"/>
<property column="cn_name" name="name" type="string"/>
<set name="airports" >
<key column="cn_id"/>
<one-to-many class="Airport"/>
</set>
</class>
除了那些非常小的方法,这种做法并不是特别地令人满意:在XML文件里编写Java代码的做法很容易出错而且难于维护。
使用SQL表达式有时业务逻辑(特别地如果引入了聚合,求和,合计等运算)可能会更自然地用SQL表达式来定义:
<property name="orderTotal" type="java.lang.Double"
formula="(select sum(item.amount)
from item
where item.order_id = order_id)" />
在多数情况下这是非常好的解决方案。但是,必须注意的是每次Hibernate从数据库加载对象时都会执行查询的动作,这可能会对性能造成影响。
使用基类你也可以用generated-class元属性来定义基类,hbm2java会用这些元属性生成基类,这样你就可以在所生成基类的子类中自由地添加业务逻辑。例如,我们可以在Country类上应用这种技术,就象下面所描述的:
<class name="Country" table="COUNTRY" dynamic-update="true">
<meta attribute="implement-equals">true</meta>
<meta attribute="generated-class">CountryBase</meta>
<meta attribute="scope-field">protected</meta>
<id name="id" type="long" unsaved-value="null" >
<column name="cn_id" not-null="true"/>
<generator class="increment"/>
</id>
<property column="cn_code" name="code" type="string"/>
<property column="cn_name" name="name" type="string"/>
<set name="airports" >
<key column="cn_id"/>
<one-to-many class="Airport"/>
</set>
</class>
hbm2java生成CountryBase类,此类包含了所有在映射文件中描述的属性,getter,setter等。接着,你可以在Country的派生类中自由地添加业务逻辑,这些会被Hibernate使用并实例化,例如:
public class Country extends CountryBase {
/**
* Add an airport to this country
*/
public void addAirport(Airport airport) {
airport.setCountry(this);
if (getAirports() == null) {
setAirports(new java.util.HashSet());
}
getAirports().add(airport);
}
}
包装(Wrapper)或委派(Delegate)模式(Pattern)对于更复杂的业务逻辑,你或许也想使用下列技术中的一种:
· 你可以定义“wrapper”或“delegate”类,这些类含有作为属性的Domain类,并且提供了指定域类额外的业务逻辑。
· 你可能更喜欢“服务(service)”或“外观(façade)”方法,“façade”对象(如无状态的会话EJB)提供了一套相关的业务服务来操作Domain对象。
结论本文描述了我们用来管理Hibernate映射的一种方法, 这在我们所特定的环境中工作得很好。 当然,还有许多别的方法。或许本文会给你的项目提供一些想法,但无论你做什么, 总要使用最适合你项目的方法。
资源· Hibernate
· Hibernate Tools
· Ant
· Hibernate Ant tool
· Maven
John Ferguson Smart从1991起涉足IT行业, 99年开始从事J2EE的开发。
相关推荐
根据实体类生成简单的Hibernate映射文件,对不用Myeclipse的童鞋还是有用
NULL 博文链接:https://skiof007.iteye.com/blog/1796910
通过Hibernate Tool 来实现通过数据库表自动生成Java类和HBM文件
Hbm2java Hbm2java用于基于HBM文件生成源。
5. 去掉了HBM文件中旧的缓存代码; 6. 修正了端口输入方式,直接在IP地址后面增加端口; 7. 完美支持数据库注解自动生成到配置文件和JAVABEAN 下个版本的计划: 1.增加数据库列表功能 2.增加主键策略
在eclipse上通过hibernate工具,将数据库表生成Java类和xml配置文件 总共有2个版本,根据自己的需求使用版本3或者5: 1. hibernate-tools-3.4.0.CR2.jar是修改完成的jar包,直接替换原来的jar包, 重启eclipse即可...
Oracle自动生成hibernate实体 首先需要有个表A0,然后以要生成实体的表名称为参数执行存储过程,生成的结果就在A0表里。
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
Hibernate逆向生成entity和hbm.xml文件这是一个视频,比文件看起来更加给力。
利用hibernate-Tools里的相关工具类,使得java实体类(POJO)、hbm映射文件、数据库表(Schema)之间可以相互转化。也就是说,只要有其中一样,就可以通过各种途径得到其它两样。如果手里已经有了其中一样东西,要想...
*.hbm.xml,*一般用映射到该类记录的Class的名称表示。 ------------------------ 开发一个Hibernate时有几个工具还是挺好用的 1. Middlegen-Hibernate,用来自动生成对象映射的配置...
包含了两个生成工具, hibernate-extensions是通过xml生成Java的 Middlegen 是通过数据库生成hbm.xml的
提供生成tools:hbm2java,ddl2java,class2java,同时hbm2java只支持hibernate2.0
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和Hibernate的整合方式 12.6.2 编写用户注册画面regedit.jsp 12.6.3 编写用户登录画面login.jsp ...
6.3 Hibernate用对象标识符(OID)来区分对象 126 6.4 Hibernate的内置标识符生成器的用法 128 6.4.1 increment标识符生成器 131 6.4.2 identity标识符生成器 133 6.4.3 sequence标识符生成器 134 6.4.4 hilo...
4.从 Database Explorer 的表定义中生成 Java 类和 Hibernate 数据库映射文件 (.hbm) 5.使用 HQL 编辑器 6.创建使用 Hibernate 的小测试应用 目录 1.前言 2.准备工作 3.介绍 4.Hibernate 一览 5.创建 ...