從資料表生成映射文件與POJO


如果您已經設計好資料表格,您可以使用Hibernate Tool自動從表格中生成映射文件或POJO,甚至是標上了Annotation的實體類別,您需要Hibernate Core、Hibernate Annotation、Freemaker、jTidy的JAR檔案,請將之存放至專案的lib資料夾中,並假設產生的相關xml與.java將放在src資料夾中。

首先,請建立一個example.db.properties,當中包括了資料庫的連接訊息:
  • example.db.properties
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class = com.mysql.jdbc.Driver
hibernate.connection.url = jdbc:mysql://localhost/demo
hibernate.connection.username = caterpillar
hibernate.connection.password = 123456

接著撰寫Ant建構檔案,相關的註解標示於其中:
  • build.xml
<project name="Hello World Reverse" default="compile" basedir=".">

<property name="proj.name" value="Reverse example"/>
<property name="proj.shortname" value="example-reverse"/>
<property name="version" value="1.0"/>

<property name="src.java.dir" value="src/java"/>
<property name="lib.dir" value="lib"/>

<path id="project.classpath">
<fileset dir="\${lib.dir}">
<include name="**/*.jar"/>
<include name="**/*.zip"/>
</fileset>
</path>

<!-- 使用HibernateToolTask -->
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="project.classpath"/>

<!-- 從資料庫產生HBM、Hibernate設定檔等XML -->
<target name="reveng.hbmxml"
description="Read database, generate XML mapping files">

<hibernatetool destdir="\${src.java.dir}">
<jdbcconfiguration
propertyfile="\${basedir}/example.db.properties"
revengfile="\${basedir}/example.reveng.xml"/>
<hbm2hbmxml/> <!-- 從資料表產生HBM -->
<hbm2cfgxml/> <!-- 產生hibernate.cfg.xml -->
</hibernatetool>

</target>

<!-- 從HBM產生POJO -->
<target name="reveng.pojos"
description="Read XML mapping files, generate POJOs">

<hibernatetool destdir="\${src.java.dir}">
<configuration>
<fileset dir="\${src.java.dir}">
<include name="**/*.hbm.xml"/>
</fileset>
</configuration>
<hbm2java/> <!-- 產生POJO -->
</hibernatetool>

</target>

<!-- 從資料表產生Annotation的實體類別 -->
<target name="reveng.entities"
description="Read database, generate Java entity beans">

<hibernatetool destdir="\${src.java.dir}">
<jdbcconfiguration
propertyfile="\${basedir}/example.db.properties"
revengfile="\${basedir}/example.reveng.xml"/>
<hbm2java jdk5="true" ejb3="true"/>
<hbm2cfgxml ejb3="true"/>
</hibernatetool>

</target>

</project>

按照上列內容,可以看到,還需要一個example.reveng.xml:
  • example.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=".*"
package="onlyfun.caterpillar"/>
</hibernate-reverse-engineering>

在這邊簡單的設定<table-filter>,match-name用regression expression來設定所要match的表格名稱,package設定Java的套件名稱。

如果建構時指定target為reveng.hbmxml,則會產生以下的TUser.hbm.xml及hibernate.cfg.xml:
  • TUser.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2007/6/26 ?U?? 12:26:43 by Hibernate Tools 3.2.0.beta8 -->
<hibernate-mapping>
<class name="onlyfun.caterpillar.TUser" table="t_user" catalog="demo">
<comment></comment>
<id name="id" type="long">
<column name="id" />
<generator class="assigned" />
</id>
<property name="name" type="string">
<column name="name">
<comment></comment>
</column>
</property>
<property name="age" type="java.lang.Long">
<column name="age">
<comment></comment>
</column>
</property>
</class>
</hibernate-mapping>

  • hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!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.password">123456</property>
<property
name="hibernate.connection.url">jdbc:mysql://localhost/demo</property>
<property
name="hibernate.connection.username">caterpillar</property>
<property
name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource="onlyfun/caterpillar/TUser.hbm.xml" />
</session-factory>
</hibernate-configuration>

如果進一步執行reveng.pojos這個target,則會產生以下的POJO:
  • TUser.java
package onlyfun.caterpillar;
// Generated 2007/6/26 下午 01:00:39 by Hibernate Tools 3.2.0.beta8

/**
* TUser generated by hbm2java
*/
public class TUser implements java.io.Serializable {

// Fields

private long id;
private String name;
private Long age;

// Constructors

/** default constructor */
public TUser() {
}

/** minimal constructor */
public TUser(long id) {
this.id = id;
}
/** full constructor */
public TUser(long id, String name, Long age) {
this.id = id;
this.name = name;
this.age = age;
}

// Property accessors
public long getId() {
return this.id;
}

public void setId(long id) {
this.id = id;
}
public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}
public Long getAge() {
return this.age;
}

public void setAge(Long age) {
this.age = age;
}
}

如果進一步執行reveng.entities這個target,則會產生以下的實體類別:
  • TUser.java
package onlyfun.caterpillar;
// Generated 2007/6/26 下午 01:02:01 by Hibernate Tools 3.2.0.beta8

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
* TUser generated by hbm2java
*/
@Entity
@Table(name="t_user"
,catalog="demo"
, uniqueConstraints = { }
)
public class TUser implements java.io.Serializable {

// Fields

private long id;
private String name;
private Long age;

// Constructors

/** default constructor */
public TUser() {
}

/** minimal constructor */
public TUser(long id) {
this.id = id;
}
/** full constructor */
public TUser(long id, String name, Long age) {
this.id = id;
this.name = name;
this.age = age;
}

// Property accessors
@Id

@Column(name="id", unique=true,
nullable=false, insertable=true, updatable=true)
public long getId() {
return this.id;
}

public void setId(long id) {
this.id = id;
}

@Column(name="name", unique=false,
nullable=true, insertable=true, updatable=true)
public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

@Column(name="age", unique=false,
nullable=true, insertable=true, updatable=true)
public Long getAge() {
return this.age;
}

public void setAge(Long age) {
this.age = age;
}
}