Hibernate中有多种可以生成代码的方法,其中:
1)Java源文件通过XDoclet工具可以生成对象-关系映射文件
2)数据库Schema通过Middlegen工具可以生成对象-关系映射文件
3)对象-关系映射文件通过hbm2java可以生成Java源文件
4)对象-关系映射文件通过hbm2ddl可以生成数据库Schema
在很多书上发现都用到了hbm2java和Ant进行整合自动生成Java源文件,今天我也来学习学习
将HibernateTools-3.2.0.beta7/plugins/org.hibernate.eclipse_3.2.0.beta7/lib/tools下面的hiberante-tools.jar和freemarker.jar以及HibernateTools-3.2.0.beta7/plugins/org.hibernate.eclipse_3.2.0.beta7/lib/hibernate下面的hibernate3.jar拷贝到lib目录,
在E:/HBMAction建立CarDemo文件夹
在E:/HBMAction/CarDemo建立lib,src子目录以及build.xml文件
+lib
一些Hibernate3.2必须的包
+src
mydemo
Car.hbm.xml
hibernate.cfg.xml
lo4j.properties
build.xml
Car.hbm.xml的内容如下:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="mydemo.Car" table="cars">
<meta attribute="class-description">
一辆简单的汽车
@author lisiding_1986
</meta>
<meta attribute="class-scope">public</meta>
<id name="carID" type="long" column="car_ID">
<meta attribute="scope-set">protected</meta>
<generator class="native" />
</id>
<property name="carName" type="String">
<meta attribute="field-description">汽车的名字</meta>
<meta attribute="use-in-toString">true</meta>
<column name="car_Name" sql-type="varchar(255)" not-null="true" />
</property>
<property name="carNumber" type="String">
<meta attribute="field-description">汽车的车牌号码</meta>
<meta attribute="use-in-toString">true</meta>
<column name="car_Number" sql-type="varchar(255)" not-null="true" />
</property>
<property name="carDate" type="timestamp">
<meta attribute="field-description">汽车的生产日期</meta>
<column name="car_Date" sql-type="timestamp" />
</property>
</class>
</hibernate-mapping>
这个对象-关系映射文件包含了如下简要信息:
这个Java源文件的名字叫Car,打包在mydemo包下,有四个字段carID,carName,carNumber,carDate,
这个类是public的,其中的carID字段的set方法是protected
接下来写Hibernate配置文件hibernate.cfg.xml
<?xml version='1.0' encoding='GB2312'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- 数据库连接设置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">12345678</property>
<!-- JDBC连接池 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">120</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3po.idle_test_period">120</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<!-- SQL 方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<!-- 打开Hibernate的自动Session上下文管理 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 在命令窗口显示所有的SQL语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 将SQL语句格式化,更方便查看 -->
<property name="hibernate.format_sql">true</property>
<!-- 在启动的时候删除数据并重新创建 -->
<property name="hbm2ddl.auto">create</property>
<!-- 指定对象-映射文件的位置 -->
<mapping resource="mydemo/Car.hbm.xml" />
</session-factory>
</hibernate-configuration>
最后就是写build.xml了
<?xml version="1.0" encoding="GB2312" ?>
<project name="CarDemo" default="hbm2java" basedir=".">
<!-- 定义存放SQL语句和Java源文件的根目录 -->
<property name="build.dir" value="build" />
<!-- 定义将哪个目录下的jar文件做为编译或生成Java源文件时的classpath -->
<property name="build.lib" value="${basedir}/lib" />
<!-- 定义将生成的SQL语句保存到哪个目录 -->
<property name="build.ddl" value="build/ddl" />
<!-- 定义将生成的Java源文件放入哪个目录 -->
<property name="build.src" value="build/src" />
<!-- 定义一个path任务,里面有各种jar文件 -->
<path id="libs">
<!-- 将src下面的各种文件也作为classpath -->
<pathelement location="${basedir}/src" />
<!-- 将各种jar文件作为id libs引用 -->
<fileset dir="${build.lib}">
<include name="*.jar" />
</fileset>
</path>
<target name="init" description="创建一个目标,将上面定义的文件夹创建好">
<!-- 执行delete任务,先删除build文件夹
<delete dir="${build.dir}" />
-->
<!-- 执行mkdir任务,创建上面定义好的文件夹 -->
<mkdir dir="${build.dir}" />
<mkdir dir="${build.src}" />
<mkdir dir="${build.ddl}" />
</target>
<target name="copy" depends="init" description="拷贝src下的文件到build.src目录">
<copy todir="${build.src}">
<fileset dir="${basedir}/src">
<include name="**/*.properties" />
<include name="**/*.hbm.xml" />
<include name="**/*.cfg.xml" />
</fileset>
</copy>
</target>
<target name="hbm2java" depends="copy" description="利用对象-关系映射文件生成Java源文件">
<taskdef name="hbm2java"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="libs" />
<hbm2java destdir="${build.src}">
<configuration configurationfile="${build.src}/hibernate.cfg.xml" />
<hbm2java jdk5="true" />
</hbm2java>
</target>
<target name="hbm2ddl" depends="copy" description="利用对象-关系映射文件生成SQL语句">
<taskdef name="hbm2ddl"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="libs" />
<hbm2ddl destdir="${build.ddl}">
<configuration configurationfile="${build.src}/hibernate.cfg.xml" />
<hbm2ddl export="true"
console="false"
create="true"
update="false"
drop="false"
outputfilename="car.sql" />
</hbm2ddl>
</target>
<!-- 将建立的目录删除 -->
<target name="clean">
<delete dir="${build.dir}" />
</target>

</project>
将CMD窗口的命令提示符转到E:/HBMAction/CarDemo,运行ant hbm2java,
可以看到在E:/HBMAction/CarDemo/build/src/mydemo文件夹中生成了Car.java,内容如下:
package mydemo;
// Generated 2007-12-6 16:30:26 by Hibernate Tools 3.2.0.beta7


import java.util.Date;


/** *//**
* 一辆简单的汽车
* @author lisiding_1986
*
*/

public class Car implements java.io.Serializable ...{

// Fields

private long carID;

/** *//**
* 汽车的名字
*/
private String carName;

/** *//**
* 汽车的车牌号码
*/
private String carNumber;

/** *//**
* 汽车的生产日期
*/
private Date carDate;

// Constructors


/** *//** default constructor */

public Car() ...{
}


/** *//** minimal constructor */

public Car(String carName, String carNumber) ...{
this.carName = carName;
this.carNumber = carNumber;
}

/** *//** full constructor */

public Car(String carName, String carNumber, Date carDate) ...{
this.carName = carName;
this.carNumber = carNumber;
this.carDate = carDate;
}
// Property accessors

public long getCarID() ...{
return this.carID;
}

protected void setCarID(long carID) ...{
this.carID = carID;
}

/** *//**
* * 汽车的名字
*/

public String getCarName() ...{
return this.carName;
}

public void setCarName(String carName) ...{
this.carName = carName;
}

/** *//**
* * 汽车的车牌号码
*/

public String getCarNumber() ...{
return this.carNumber;
}

public void setCarNumber(String carNumber) ...{
this.carNumber = carNumber;
}

/** *//**
* * 汽车的生产日期
*/

public Date getCarDate() ...{
return this.carDate;
}

public void setCarDate(Date carDate) ...{
this.carDate = carDate;
}




}



说句实话,第一次搞这东西真不容易,在网上找了很多资料,经过长达4个多小时的调试终于生成成功,激动中......
下面运行ant hbm2ddl,果然不出我所料,又是一大堆异常,我找了一下异常信息,如下:
[hbm2ddl] org.hibernate.MappingException: Could not determine type for: String
, for columns: [org.hibernate.mapping.Column(car_Name)]
经过10分钟左右后的调试,终于成功生成SQL语句,如下:
create table cars (
car_ID bigint not null auto_increment,
car_Name varchar(255) not null,
car_Number varchar(255) not null,
car_Date timestamp, primary key (car_ID)
) type=InnoDB;
总结,刚刚接触一个新东西的时候肯定会遇到各种各样的问题,但是只要不放弃,我相信终究会成功