第 20 章 工具箱指南

可以通过一系列Eclipse插件、命令行工具和Ant任务来进行与Hibernate关联的转换。

除了Ant任务外,当前的Hibernate Tools也包含了Eclipse IDE的插件,用于与现存数据库的逆向工程。

要得到更多信息,请查阅 Hibernate Tools 包及其文档。

同时,Hibernate主发行包还附带了一个集成的工具(它甚至可以在Hibernate“内部”快速运行)SchemaExport ,也就是 hbm2ddl

20.1. Schema自动生成(Automatic schema generation)

可以从你的映射文件使用一个Hibernate工具生成DDL。 生成的schema包含有对实体和集合类表的完整性引用约束(主键和外键)。涉及到的标示符生成器所需的表和sequence也会同时生成。

在使用这个工具的时候,你必须 通过hibernate.dialet属性指定一个SQL方言(Dialet),因为DDL是与供应商高度相关的。

首先,要定制你的映射文件,来改善生成的schema。

20.1.1. 对schema定制化(Customizing the schema)

很多Hibernate映射元素定义了可选的lengthprecision 或者 scale属性。你可以通过这个属性设置字段的长度、精度、小数点位数。

<property name="zip" length="5"/>
<property name="balance" precision="12" scale="2"/>

有些tag还接受not-null属性(用来在表字段上生成NOT NULL约束)和unique属性(用来在表字段上生成UNIQUE约束)。

<many-to-one name="bar" column="barId" not-null="true"/>
<element column="serialNumber" type="long" not-null="true" unique="true"/>

unique-key属性可以对成组的字段指定一个唯一键约束(unique key constraint)。目前,unique-key属性指定的值在生成DDL时并不会被当作这个约束的名字,它们只是在用来在映射文件内部用作区分的。

<many-to-one name="org" column="orgId" unique-key="OrgEmployeeId"/>
<property name="employeeId" unique-key="OrgEmployee"/>

index属性会用对应的字段(一个或多个)生成一个index,它指出了这个index的名字。如果多个字段对应的index名字相同,就会生成包含这些字段的index。

<property name="lastName" index="CustName"/>
<property name="firstName" index="CustName"/>

foreign-key属性可以用来覆盖任何生成的外键约束的名字。

<many-to-one name="bar" column="barId" foreign-key="FKFooBar"/>

很多映射元素还接受<column>子元素。这在定义跨越多字段的类型时特别有用。

<property name="name" type="my.customtypes.Name"/>
    <column name="last" not-null="true" index="bar_idx" length="30"/>
    <column name="first" not-null="true" index="bar_idx" length="20"/>
    <column name="initial"/>
</property>

default属性为字段指定一个默认值 (在保存被映射的类的新实例之前,你应该将同样的值赋于对应的属性)。

<property name="credits" type="integer" insert="false">
    <column name="credits" default="10"/>
</property>
<version name="version" type="integer" insert="false">
    <column name="version" default="0"/>
</property>

sql-type属性允许用户覆盖默认的Hibernate类型到SQL数据类型的映射。

<property name="balance" type="float">
    <column name="balance" sql-type="decimal(13,3)"/>
</property>

check属性允许用户指定一个约束检查。

<property name="foo" type="integer">
    <column name="foo" check="foo > 10"/>
</property>
<class name="Foo" table="foos" check="bar < 100.0">
    ...
    <property name="bar" type="float"/>
</class>

表 20.1. Summary

属性(Attribute)值(Values)解释(Interpretation)
length数字字段长度
precision数字精度(decimal precision)
scale数字小数点位数(decimal scale)
not-nulltrue|false指明字段是否应该是非空的
uniquetrue|false指明是否该字段具有惟一约束
indexindex_name指明一个(多字段)的索引(index)的名字
unique-keyunique_key_name指明多字段惟一约束的名字(参见上面的说明)
foreign-keyforeign_key_name specifies the name of the foreign key constraint generated for an association, for a <one-to-one>, <many-to-one>, <key>, or <many-to-many> mapping element. Note that inverse="true" sides will not be considered by SchemaExport. 指明一个外键的名字,它是为关联生成的,或者<one-to-one><many-to-one>, <key>, 或者<many-to-many>映射元素。注意inverse="true"SchemaExport时会被忽略。
sql-typeSQL 字段类型 覆盖默认的字段类型(只能用于<column>属性)
defaultSQL表达式 为字段指定默认值
checkSQL 表达式 对字段或表加入SQL约束检查

<comment>元素可以让你在生成的schema中加入注释。

<class name="Customer" table="CurCust">
    <comment>Current customers only</comment>
    ...
</class>
<property name="balance">
    <column name="bal">
        <comment>Balance in USD</comment>
    </column>
</property>

结果是在生成的DDL中包含comment on table 或者 comment on column语句(假若支持的话)。

20.1.2. 运行该工具

SchemaExport工具把DDL脚本写到标准输出,同时/或者执行DDL语句。

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaExport options mapping_files

表 20.2. SchemaExport命令行选项

选项说明
--quiet不要把脚本输出到stdout
--drop只进行drop tables的步骤
--create只创建表
--text不执行在数据库中运行的步骤
--output=my_schema.ddl把输出的ddl脚本输出到一个文件
--naming=eg.MyNamingStrategy选择一个命名策略(NamingStrategy)
--config=hibernate.cfg.xml从XML文件读入Hibernate配置
--properties=hibernate.properties从文件读入数据库属性
--format把脚本中的SQL语句对齐和美化
--delimiter=;为脚本设置行结束符

你甚至可以在你的应用程序中嵌入SchemaExport工具:

Configuration cfg = ....;
new SchemaExport(cfg).create(false, true);

20.1.3. 属性(Properties)

可以通过如下方式指定数据库属性:

  • 通过-D<property>系统参数

  • hibernate.properties文件中

  • 位于一个其它名字的properties文件中,然后用 --properties参数指定

所需的参数包括:

表 20.3. SchemaExport 连接属性

属性名说明
hibernate.connection.driver_classjdbc driver class
hibernate.connection.urljdbc url
hibernate.connection.usernamedatabase user
hibernate.connection.passworduser password
hibernate.dialect方言(dialect)

20.1.4. 使用Ant(Using Ant)

你可以在你的Ant build脚本中调用SchemaExport:

<target name="schemaexport">
    <taskdef name="schemaexport"
        classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
        classpathref="class.path"/>
    
    <schemaexport
        properties="hibernate.properties"
        quiet="no"
        text="no"
        drop="no"
        delimiter=";"
        output="schema-export.sql">
        <fileset dir="src">
            <include name="**/*.hbm.xml"/>
        </fileset>
    </schemaexport>
</target>

20.1.5. 对schema的增量更新(Incremental schema updates)

SchemaUpdate工具对已存在的schema采用"增量"方式进行更新。注意SchemaUpdate严重依赖于JDBC metadata API,所以它并非对所有JDBC驱动都有效。

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaUpdate options mapping_files

表 20.4. SchemaUpdate命令行选项

选项说明
--quiet不要把脚本输出到stdout
--text不把脚本输出到数据库
--naming=eg.MyNamingStrategy选择一个命名策略 (NamingStrategy)
--properties=hibernate.properties从指定文件读入数据库属性
--config=hibernate.cfg.xml指定一个 .cfg.xml文件

你可以在你的应用程序中嵌入SchemaUpdate工具:

Configuration cfg = ....;
new SchemaUpdate(cfg).execute(false);

20.1.6. 用Ant来增量更新schema(Using Ant for incremental schema updates)

你可以在Ant脚本中调用SchemaUpdate

<target name="schemaupdate">
    <taskdef name="schemaupdate"
        classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
        classpathref="class.path"/>
    
    <schemaupdate
        properties="hibernate.properties"
        quiet="no">
        <fileset dir="src">
            <include name="**/*.hbm.xml"/>
        </fileset>
    </schemaupdate>
</target>

20.1.7. Schema 校验

SchemaValidator工具会比较数据库现状是否与映射文档“匹配”。注意,SchemaValidator 严重依赖于JDBC的metadata API,因此不是对所有的JDBC驱动都适用。这一工具在测试的时候特别有用。

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaValidator options mapping_files

表 20.5. SchemaValidator命令行参数

选项描述
--naming=eg.MyNamingStrategy选择一个命名策略 (NamingStrategy)
--properties=hibernate.properties从文件中读取数据库属性
--config=hibernate.cfg.xml指定一个.cfg.xml文件

你可以在你的应用程序中嵌入SchemaValidator

Configuration cfg = ....;
new SchemaValidator(cfg).validate();

20.1.8. 使用Ant进行schema校验

你可以在Ant脚本中调用SchemaValidator:

<target name="schemavalidate">
    <taskdef name="schemavalidator"
        classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
        classpathref="class.path"/>
    
    <schemavalidator
        properties="hibernate.properties">
        <fileset dir="src">
            <include name="**/*.hbm.xml"/>
        </fileset>
    </schemaupdate>
</target>