Hibernate代码生成器可以用来为Hibernate映射文件生成Java实现类的骨架。这个工具在Hibernate Extensions发行包中提供(需要单独下载)。
hbm2java解析映射文件,生成可工作的Java源代码文件。使用hbm2java,你可以“只”提供.hbm文件,不用担心要去手工编写Java文件。
java -cp hibernate_classpaths net.sf.hibernate.tool.hbm2java.CodeGenerator options mapping_files
Table 19.5. 代码生成器命令行选项
| 选项 | 说明 | 
|---|---|
| --output=output_dir | 生成代码输出的根目录 | 
| --config=config_file | 可选的hvm2java配置文件 | 
配置文件提供了配置生成源代码的多个"渲染器(renders)"的途径,也可以声明在全局范围生效的<meta>属性。详情请参见<meta>属性的部分。
<codegen>
    <meta attribute="implements">codegen.test.IAuditable</meta>
    <generate renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"/>
    <generate
        package="autofinders.only"
        suffix="Finder"
        renderer="net.sf.hibernate.tool.hbm2java.FinderRenderer"/>
</codegen>
这个配置文件声明了一个全局的meta(元)属性“implements”,指定了两个渲染器,默认渲染器(BadicRender)和生成Finder(参见下面的“基本Finder 生成器”)的渲染器。
定义第二个渲染器需要一个包名和后缀属性。
包名属性指定生成后的源代码应该保存的位置,覆盖在.hbm文件中指定的包范围。
后缀属性指定生成的文件的后缀。比如说,如果有一个Foo.java文件,应该变成FooFinder.java。
<meta>标签时对hbm.xml文件进行的简单注解,工具可以用这个位置来保存/阅读和Hibernate内核不是直接相关的一些信息。
你可以用<meta>标签来告诉hbm2java只生成"protectd"
下面的例子:
<class name="Person">
    <meta attribute="class-description">
        Javadoc for the Person class
        @author Frodo
    </meta>
    <meta attribute="implements">IAuditable</meta>
    <id name="id" type="long">
        <meta attribute="scope-set">protected</meta>
        <generator class="increment"/>
    </id>
    <property name="name" type="string">
        <meta attribute="field-description">The name of the person</meta>
    </property>
</class>
会生成类似下面的输出(为了有助于理解,节选部分代码)。注意Javadoc注释和声明成protected的set方法:
// default package
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/** 
 *         Javadoc for the Person class
 *         @author Frodo
 *     
 */
public class Person implements Serializable, IAuditable {
    /** identifier field */
    public Long id;
    /** nullable persistent field */
    public String name;
    /** full constructor */
    public Person(java.lang.String name) {
        this.name = name;
    }
    /** default constructor */
    public Person() {
    }
    public java.lang.Long getId() {
        return this.id;
    }
    protected void setId(java.lang.Long id) {
        this.id = id;
    }
    /** 
     * The name of the person
     */
    public java.lang.String getName() {
        return this.name;
    }
    public void setName(java.lang.String name) {
        this.name = name;
    }
}
Table 19.6. 支持的meta标签
| 属性 | 说明 | 
|---|---|
| class-description | 插入到类的javadoc说明去 | 
| field-description | 插入到field/property的javadoc说明去 | 
| interface | 如果是true,生成interface而非class | 
| implements | 类要实现的接口 | 
| extends | 类要继承的超类(若是subclass,则忽略该属性) | 
| generated-class | 重新指定要生成的类名 | 
| scope-class | class的scope | 
| scope-set | set方法的scope | 
| scope-get | get方法的scope | 
| scope-field | 实际属性字段(field)的scope | 
| use-in-tostring | 在toString()中包含此属性 | 
| bound | 为属性增加propertyChangeListener支持 | 
| constrained | 为属性增加vetoChangeListener支持 | 
| gen-property | 如果是false,不会生成属性(谨慎使用) | 
| property-type | 覆盖属性的默认值.如果值是标签,则指定一个具体的类型而非Object(Use this with any tag's to specify the concrete type instead of just Object.) | 
| finder-method | 参见下面的"Basic finder generator" | 
| session-method | 参见下面的"Basic finder generator" | 
通过<meta>标签定义的属性在一个hbm.xml文件中是默认"继承"的。
这究竟是什么意思?如果你希望你所有的类都实现IAuditable接口,那么你只需要加一个<meta attribute="implements">IAuditable</meta> 在你hml.xml文件的开头,就在<hibernate-mapping>后面。现在所有在hbm.xml文件中定义的类都会实现IAuditable了!(除了那些也特别指定了"implements"元属性的类,因为本地指定的元标签总是会覆盖任何继承的元标签)。
注意,这条规则对所有 的<meta>标签都有效。也就是说它可以用来指定所有的字段都被声明成protected的,而非默认的private。这可以通过在<class>后面<meta attribute="scope-field">protected</meta>指定,那么这个类所有的field都会变成protected。
如果你不想让<meta>标签继承,你可以简单的在标签属性上指明inherit="false",比如<meta attribute="scope-class" inherit="false">public abstract</meta>,这样"class-scope"就只会对当前类起作用,不会对其子类生效。
目前可以让hbm2java为Hibernate属性生成基本的finder。这需要在hbm.xml文件中做两件事情。
首先是要标记出你希望生成finder的字段。你可以通过在property标签中的meta 块来定义:
<property name="name" column="name" type="string">
     <meta attribute="finder-method">findByName</meta>
</property>
find方法的名字就是meta标签中间的文字。
第二件事是为hbm2java建立下面格式的配置文件:
<codegen>
    <generate renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"/>
    <generate suffix="Finder" renderer="net.sf.hibernate.tool.hbm2java.FinderRenderer"/>
</codegen>
然后用参数去调用:hbm2java --config=xxx.xml,xxx.xml就是你刚才创建的配置文件的名字。
有个可选的参数,作为一个在class级别的meta标签,格式如下:
<meta attribute="session-method">
    com.whatever.SessionTable.getSessionTable().getSession();
</meta>
他是用来管理你如何使用Thread Local Session模式(在Hibernate 网站的Design Patterns部分有文档)得到session的。
目前可以使用velocity作为渲染机制的一个替代方案。下面的config.xml文件显示了如果配置hbm2java来使用velocity渲染器。
    <codegen>
     <generate renderer="net.sf.hibernate.tool.hbm2java.VelocityRenderer">
      <param name="template">pojo.vm</param>
     </generate>
    </codegen>
名为template的参数是指向你希望你使用velocity macro文件的资源路径。这个文件必须在hbm2java的classpath中。所以要记住把pojo.vm所在的路径加入到你ant任务或者shell脚本中去。(默认的位置是./tools/src/velocity)
注意,当前的pojo.vm只生成java beans最基本的部分。他还没有默认的渲染器那么完整,也没有那么多功能——特别是大部分meta标签还不支持。