反向工程遗留数据库

      当映射遗留数据库时,第一步可能涉及一个自动的反向工程过程。毕竟,实体Schema已经存在于你的数据库系统中。为了使这项工作更容易些,Hibernate配有一组工具,可以从这个元数据(包括XML映射文件和Java源代码)中读取Schema,并生成各种需要创建的东西。所有这些都是基于模板的,因此许多定制工作成了可能。


我们将首先介绍如何编写一个可以把现有的数据库加载到Hibernate元数据模型中的Ant目标。


创建数据库配置

要从现有的数据库中生成映射和代码,首先需要创建一个包含数据库连接设置的配置文件:


hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.url=jdbc:oracle:thin:@localhost:1521:orcl
hibernate.connection.username=system
hibernate.connection.password=bdqn
hibernate.dialect=org.hibernate.dialaect.OracleDialect

      直接把这个文件保存在项目下,并命名为helloworld.db.properties。这里显示的五行是连接到数据库并读取所有表和列所需的最少代码。你可能已经创建了一个Hibernate XML配置文件,而不是helloworld.db.properties,但是没有必要把这弄得比需要的更复杂。


接下来编写Ant目标。在项目的一个build.xml文件中,添加下列代码:


<taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="project.classpath" />
<target name="reveng.hbmxml">
		<hibernatetool destdir="${basedir}/src">
			<jdbcconfiguration propertyfile="${basedir}/helloworld.db.properties" revengfile="${basedir}/helloworld.reveng.xml" />
			<!--导出实体映射文件-->
			<hbm2hbmxml />
			<!--导出hibernate.cfg.xml文件-->
			<hbm2cfgxml />
		</hibernatetool>
	</target>

      Ant的这个HibernateToolTask定义和以前的一样。假设你将重用前面章节中介绍过的大部分构建文件,并且如project.classpath这样的引用也是一样的。


<jdbcconfiguration>是一个Hibernate工具配置,可以通过JDBC连接到数据库,以及从数据库目录中读取JDBC元数据。通常用两个选项对它进行配置:数据库连接(属性文件)和一个可选的反射工程定制文件。


      然后,由工具配置生成的元数据被导入到导出器。这个范例的Ant目标命名了这样两个导出器:hbm2hbmxml导出器,就像你能从它的命名中猜到的那样,它从配置中取出Hibernate元数据(hbm),并生成Hibernate XML映射文件;第二个导出器可以生成一个hibernate.cfg.xml文件,该文件列出所有生成的XML映射文件。


在谈论这些以及各种其他的导出器之前,要花点时间讨论反射工程定制文件以及如何使用它。


定制反向工程

      JDBC元数据——也就是说,你可以通过JDBC从一个数据库中读取有关它自身的信息——通常不足以创建一个完美的XML映射文件,至于Java应用代码更不必说了。可以用一个使用XML语法的反向工程配置文件定制反射工程的过程。


helloworld.reveng.xml文件


<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-reverse-engineering SYSTEM
	"http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering>
	<table-filter match-name="TBL_MESSAGE" package="cn.jbit.hibernate.entity" />
	<table name="TBL_MESSAGE" schema="SYSTEM" class="Message">
		<primary-key>
			<generator class="native" />
			<key-column name="MESSAGE_ID" property="id" type="long"/>
		</primary-key>
		<column name="MESSAGE_TEXT" property="text" type="string"/>
		<foreign-key constraint-name="FK_NEXT_MESSAGE">
			<many-to-one property="nextMessage"/>
			<set exclude="true"/>
		</foreign-key>
	</table>
</hibernate-reverse-engineering>

      如果现在使用这个定制运行Ant目标,它就会在源目录的hello包中生成Message.hbm.xml文件。(首先要把Freemarker和jTidy JAR文件复制到你的库目录里面)。


生成Java源代码

      可以使用在Ant构建中的Hibernate Tools和hbm2java导出器生成用于实体类的源代码。这个源工具可以是任何能够被读进Hibernate元数据模型的东西——如果你想要定制Java代码生成,Hibernate XML映射文件是最好的。


把下列目标添加到Ant构建:


<!--实体类生成-->
	<target name="reveng.pojos" description="实体类生成">
		<hibernatetool destdir="${basedir}/src">
			<configuration>
				<fileset dir="${basedir}/src">
					<include name="**/*.hbm.xml" />
				</fileset>
			</configuration>
			<hbm2java jdk5="true" />
		</hibernatetool>
	</target>

<configuration>读取所有的Hibernate XML映射文件,<hbm2java>导出器通过默认的策略生成Java源代码。


生成Java Persistence实体类

      一般地,在实体类源代码中使用Hibernate XML映射文件或者JPA注解来定义映射元数据,因此从XML映射文件中生成包含注解的Java Persistence实体类不太合理。然而,可以直接从JDBC元数据中创建包含注解的实体类源代码,并跳过XML映射步骤。看看下列Ant目标:


<!--生成Java Persistence实体类-->
	<target name="reveng.entities" description="生成Java Persistence实体类">
		<hibernatetool destdir="${basedir}/src">
			<jdbcconfiguration propertyfile="${basedir}/helloworld.db.properties" revengfile="${basedir}/helloworld.reveng.xml" />
			<hbm2java jdk5="true" ejb3="true"/>
			<hbm2cfgxml ejb3="true"/>
		</hibernatetool>
	</target>

      这个目标生成包含映射注解的实体类源代码和列有这些被映射类的hibernate.cfg.xml文件。可以直接编辑Java源代码来定制映射,如果在反向工程自定义文件中定制太受限制的话。


      还要注意所有的导出器都依赖于以FreeMarker模板语言编写的模板。可以用任何喜欢的方式定制模板,甚至可以编写自己的模板。


Hibernate Tools提供的其他导出器和配置如下:


<annotationconfiguration>取代一般的<configuration>,如果你想要从被注解的Java类中读取映射元数据,而不是从XML映射文件中读取的话。它唯一的实参是包含一列已注解类的hibernate.cfg.xml文件的位置和名称。使用这种方法从被注解的类中导出一个数据库Schema。


<ejb3configuration>相当于<annotationconfiguration>,除了它可以自动在classpath中扫描被注解的Java类之外;它不需要hibernate.cfg.xml文件。


<hbm2dao>导出器可以基于数据访问对象模式,给持久层创建额外的Java源代码。


<hbm2doc>导出器生成给表和Java实体提供文档的HTML文件。


<hbmtemplate>导出器可以用一组定制的FreeMarker模板参数化,Hibernate Tools捆绑了利用JBoss Seam框架来生成完整的、可运行的骨架应用程序的框架。