從映射文件生成資料表


在您撰寫好*.hbm.xml映射文件之後,您可以使用org.hibernate.tool.hbm2ddl.SchemaExport來自動建立資料 庫表格,假設您的User.hbm.xml如下:
  • User.hbm.xml
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.User"
table="T_USER">

<id name="id" column="id">
<generator class="native"/>
</id>

<property name="name" column="name"/>

<property name="age" column="age"/>

</class>

</hibernate-mapping>

在hibernate.cfg.xml中設定JDBC等相關設定:
  • 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>

<!-- 顯示實際操作資料庫時的SQL -->
<property name="show_sql">true</property>
<!-- 將顯示的SQL排版,方便觀看 -->
<property name="format_sql">true</property>
<!-- SQL方言,這邊設定的是MySQL -->
<property
name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- JDBC驅動程式 -->
<property
name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- JDBC URL -->
<property
name="connection.url">jdbc:mysql://localhost/demo</property>
<!-- 資料庫使用者 -->
<property name="connection.username">caterpillar</property>
<!-- 資料庫密碼 -->
<property name="connection.password">123456</property>
<!-- C3P0 連接池設定 -->
<property name="c3p0.min_size">5</property>
<property name="c3p0.max_size">20</property>
<property name="c3p0.timeout">1800</property>
<property name="c3p0.max_statements">50</property>


<!-- 物件與資料庫表格映射文件 -->
<mapping resource="onlyfun/caterpillar/User.hbm.xml"/>

</session-factory>

</hibernate-configuration>

可撰寫一個程式如下:
  • HbmToTable.java
package onlyfun.caterpillar;

import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class HbmToTable {
public static void main(String[] args) {
Configuration config = new Configuration().configure();
System.out.println("Creating tables...");
SchemaExport schemaExport = new SchemaExport(config);
schemaExport.create(true, true);
}
}

SchemaExport的create()方法第一個true表示顯示SQL語法至標準輸出,第二個true表示立即在資料庫中運行SQL語法,運行程式之後,將會有以下的結果:
Creating tables...
13:59:23,765  INFO SchemaExport:154 - Running hbm2ddl schema export
13:59:23,781 DEBUG SchemaExport:170 - import file not found: /import.sql
13:59:23,781  INFO SchemaExport:179 - exporting generated schema to database

    drop table if exists T_USER
13:59:24,734 DEBUG SchemaExport:303 -
    drop table if exists T_USER

    create table T_USER (
        id bigint not null auto_increment,
        name varchar(255),
        age bigint,
        primary key (id)
    )
13:59:24,921 DEBUG SchemaExport:303 -
    create table T_USER (
        id bigint not null auto_increment,
        name varchar(255),
        age bigint,
        primary key (id)
    )
13:59:25,046  INFO SchemaExport:196 - schema export complete


生成的資料表如下:
+--------+-----------------+------+------+----------+---------------------+
| Field  | Type            | Null | Key  | Default  | Extra               |
+--------+-----------------+------+------+----------+---------------------+
| id     | int(11)         |      | PRI  | NULL     | auto_increment      |
| name   | varchar(255)    | YES  |      | NULL     |                     |
| age    | int(11)         | YES  |      | NULL     |                     |
+--------+-----------------+------+------+-----------+--------------------+
3 rows in set (0.00 sec)


您也可以在Hibernate設定檔中,加上hbm2ddl.auto的屬性設定為create
...
<!-- 重建資料表 -->

    <property name="hbm2ddl.auto">create</property>
...

加上以上的設定,在SessionFactory建立的時候,會先刪除資料表,然後進行資料表的建立。
您可以在Classpath下設定一個import.sql,在建立表格之後,接著會載入import.sql的內容,您可以在當中進行表格資料的新增SQL語句。

您還可以使用create-drop設定,這會在每一次SessionFactory關閉時,就刪除資料表。

如果映射HBM檔案隨著專案進行而有所變更,則可以使用SchemaUpdate來直接進行資料表欄位對應更新,例如:
Configuration config = new Configuration().configure();
SchemaUpdate schemaUpdate = new SchemaUpdate(config);
schemaUpdate.execute(true);

這對資料表中己有的欄位不會有影響,如果映射檔案中設定屬性有而
沒有對應的表格欄位,則會在表格上予以新增欄位,true表示在標準輸出中顯示更新的SQL語法,您也可以直接在設定檔的hbm2dll.auto屬性上設定update來達到相同的作用:
<!-- 重建資料表 -->
    <property name="hbm2ddl.auto">update</property>
...

如果hbm2ddl.auto屬性為validate設定,則會檢查映射檔案中的屬性是否都有對應的表格欄位,如果沒有對應的欄位,則會直接丟出例外,如果使用程式方式控制,則是使用SchemaValidator,例如:
Configuration config = new Configuration().configure();
SchemaValidator schemaValidator = new SchemaValidator(config);
schemaValidator.validate();

如果您想要在ANT中使用<hbm2dll>標籤來為您進行以上的功能,則您要下載Hibernate Tools,將當中的hibernate-tools.jar加入Classpath之中,然後在建構檔案中如下設定:
  • build.xml
<project name="HibernateDemo" default="schemaexport" basedir=".">
<property name="proj.name" value="HibernateGossip"/>
<property name="proj.version" value="1.0"/>
<property name="src.java.dir" value="src"/>
<property name="lib.dir" value="lib"/>
<property name="build.dir" value="bin"/>

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

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

<target name="schemaexport">
<hibernatetool destdir="\${basedir}">
<classpath path="\${build.dir}"/>
<configuration
configurationfile="\${build.dir}/hibernate.cfg.xml"/>
<hbm2ddl
drop="true"
create="true"
export="true"
outputfilename="helloworld-dll.sql"
delimiter=";"
format="true"/>
</hibernatetool>
</target>
</project>

如果drop設定為true,則建構開始時,所有的表格都會被移除,如果create設定為true,則所有的表格會隨之 重建,如果export設定為true,則SQL會直接在資料庫中運行,outputfilename為產生的SQL所存放之檔案,delimiter為 每句SQL後的分隔字元,format設定為true時SQL會適當的排版,以增加可讀性。