📄 toolsetguide.html
字号:
</p><p> 第二件事是为hbm2java建立下面格式的配置文件: </p><pre class="programlisting"><codegen> <generate renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"/> <generate suffix="Finder" renderer="net.sf.hibernate.tool.hbm2java.FinderRenderer"/></codegen></pre><p> 然后用参数去调用:<tt class="literal">hbm2java --config=xxx.xml</tt>,<tt class="literal">xxx.xml</tt>就是你刚才创建的配置文件的名字。 </p><p> 有个可选的参数,作为一个在class级别的meta标签,格式如下: </p><pre class="programlisting"><meta attribute="session-method"> com.whatever.SessionTable.getSessionTable().getSession();</meta></pre><p> 他是用来管理你如何使用<span class="emphasis"><em>Thread Local Session</em></span>模式(在Hibernate 网站的Design Patterns部分有文档)得到session的。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="toolsetguide-s2-4"></a>15.2.4. 基于Velocity的渲染器/生成器(Velocity based renderer/generator)</h3></div></div><div></div></div><p> 目前可以使用velocity作为渲染机制的一个替代方案。下面的config.xml文件显示了如果配置hbm2java来使用velocity渲染器。 </p><pre class="programlisting"> <codegen> <generate renderer="net.sf.hibernate.tool.hbm2java.VelocityRenderer"> <param name="template">pojo.vm</param> </generate> </codegen></pre><p> 名为<tt class="literal">template</tt>的参数是指向你希望你使用velocity macro文件的资源路径。这个文件必须在hbm2java的classpath中。所以要记住把pojo.vm所在的路径加入到你ant任务或者shell脚本中去。(默认的位置是<tt class="literal">./tools/src/velocity</tt>) </p><p> 注意,当前的<tt class="literal">pojo.vm</tt>只生成java beans最基本的部分。他还没有默认的渲染器那么完整,也没有那么多功能——特别是大部分<tt class="literal">meta</tt>标签还不支持。 </p></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="toolsetguide-s3"></a>15.3. 映射文件生成器(Mapping File Generation)</h2></div></div><div></div></div><p> 映射文件的骨架可以从编译过的持久化类中使用<tt class="literal">MapGenerator</tt>工具生成。这工具是Hibernate Extensions发行包的一部分。 </p><p> Hibernate映射生成器提供了从编译过的类中产生映射的机制。他使用Java反射来查找<span class="emphasis"><em>属性(properties)</em></span>,然后使用启发式算法来从属性类型猜测合适的映射。生成出来的映射文件之应该看作是后续工作的起点。没有办法在没有用户修正的情况下生成完整的Hibernate映射。但是,这个工具还是替你做了很多非常琐碎和麻烦的工作。 </p><p> 类一个一个地加入到映射去。如果工具认为某个类不是<span class="emphasis"><em>Hibernate可持久化( persistable)</em></span>的,就会把这些类剔除。 </p><p> 判断是否是<span class="emphasis"><em>Hibernate可持久化( persistable)</em></span>的原则是: </p><div class="itemizedlist"><ul type="disc" compact><li><p>必定不是一个原始类型</p></li><li><p>必定不是一个数组</p></li><li><p>必定不是一个接口</p></li><li><p>必定不是一个内部类</p></li><li><p>必定有一个默认的无参数的构造方法。</p></li></ul></div><p> 注意,接口和内部类实际上是可以通过Hibernate持久化的,但是一般来说用户不会使用。 </p><p> 对已经发现的类,<tt class="literal">MapGenerator</tt>会重复回溯到超类链条上去,以尽可能的把Hibernate可持久化的超类加入到对同一个数据库表的映射去。如果回溯过程中某个类出现了有个属性在下列<span class="emphasis"><em>备选UID名字(candidate UID names)</em></span>名单中,回溯就会停止。 </p><p> 默认的备选UID属性名有:<tt class="literal">uid</tt>, <tt class="literal">UID</tt>, <tt class="literal">id</tt>, <tt class="literal">ID</tt>, <tt class="literal">key</tt>, <tt class="literal">KEY</tt>, <tt class="literal">pk</tt>, <tt class="literal">PK</tt>。 </p><p> 如果类中有两个方法,一个是setter,一个是getter,并且setter的单参数的属性和getter的无参数返回值得类型相同,并且setter返回<tt class="literal">void</tt>,就认为发现了一个属性。并且,setter的名字必须以<tt class="literal">set</tt>字符串开始,getter的名字必须以<tt class="literal">get</tt>开始,或者以<tt class="literal">is</tt>开始并且属性类型是boolean。在上面的情况发生时,get和set之后的名字还必须匹配。这个匹配就是属性的名字,然后如果第二个字母是小写的话,会把其首字母变成小写。 </p><p> 用来决定每个属性的数据库类型的规则如下: </p><div class="orderedlist"><ol type="1" compact><li><p> 如果Java类型是<tt class="literal">Hibernate.basic()</tt>,则属性是该类型的一个普通字段。 </p></li><li><p> 对于<tt class="literal">hibernate.type.Type</tt>特定类型和<tt class="literal">PersistentEnum</tt>来说,也会使用一个普通字段。 </p></li><li><p> 如果属性类型是一个数组,那么会使用一个Hibernate数组,并且<tt class="literal">MapGenerator</tt>试图反映数组元素的类型。(attempts to reflect on the array element type.) </p></li><li><p> 如果属性是<tt class="literal">java.util.List</tt>,<tt class="literal">java.util.Map</tt>或者<tt class="literal">java.util.Set</tt>,会使用对应的Hibernate类型,但是<tt class="literal">MapGenerator</tt>不能对这些类型进行进一步处理了。 </p></li><li><p> 如果属性的类型不是上面任何一种,<tt class="literal">MapGeneraotr</tt>把决定数据库类型的步骤留待所有的类都被处理之后再来做。在那时候,如果类在上面描述过的超类搜索过程中被发现了,这个属性会被认为是一个<tt class="literal">many-to-one</tt>的关联。如果类有人和属性,它则是一个<tt class="literal">组件(component)</tt>。否则它就是可序列化的(serializable),或者不是可持久化的。 </p></li></ol></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="toolsetguide-s3-1"></a>15.3.1. 运行此工具</h3></div></div><div></div></div><p> 这个工具会把XML映射写入到标准输出或者/并且到一个文件中去。 </p><p> 在调用这个工具的时候,你必须把你编译过的类放到classpath中去。 </p><p> <tt class="literal">java -cp </tt><span class="emphasis"><em>hibernate_and_your_class_classpaths</em></span> <tt class="literal">net.sf.hibernate.tool.class2hbm.MapGenerator</tt> <span class="emphasis"><em>options and classnames</em></span> </p><p> 有两种操作模式:命令行或者交互式。 </p><p> 交互式模式当你使用一个惟一的命令行参数<tt class="literal">--interact</tt>的时候启动。这个模式提供一个命令控制台。你可以用<tt class="literal">uid=XXX</tt>命令设置每个类的UID属性的名字,<tt class="literal">XXX</tt>就是UID属性名。其他可用的命令就是类名的全限定名,或者“done”命令用来输出XML,并且结束。 </p><p> 在命令行模式下,下面的参数选项和所需处理的类的全限定名可以相互间隔使用。大多数选项会使用多次,每个只影响其后出现的类。 </p><div class="table"><a name="d0e10053"></a><p class="title"><b>表 15.7. MapGenerator命令行选项</b></p><table summary="MapGenerator命令行选项" border="1"><colgroup><col><col></colgroup><thead><tr><th>选项</th><th>说明</th></tr></thead><tbody><tr><td><tt class="literal">--quiet</tt></td><td>不把O-R 映射输出到stdout</td></tr><tr><td><tt class="literal">--setUID=uid</tt></td><td>设置备选UID名单</td></tr><tr><td><tt class="literal">--addUID=uid</tt></td><td>在备选UID名单前面增加一个新的uid</td></tr><tr><td><tt class="literal">--select=</tt><span class="emphasis"><em>mode</em></span></td><td>对后面的classes使用select选择的<span class="emphasis"><em>模式(mode)</em></span>(比如, <span class="emphasis"><em>distinct</em></span> 或者<span class="emphasis"><em>all</em></span>)</td></tr><tr><td><tt class="literal">--depth=<small-int></tt></td><td>限制后面的类的组件数据递归层数</td></tr><tr><td><tt class="literal">--output=my_mapping.xml</tt></td><td>把O-R 映射输出到一个文件</td></tr><tr><td><span class="emphasis"><em>full.class.Name</em></span></td><td>把这个类加入到映射中</td></tr><tr><td><tt class="literal">--abstract=</tt><span class="emphasis"><em>full.class.Name</em></span></td><td>参见下面的说明</td></tr></tbody></table></div><p> abstract开关指定本工具忽略特定的超类,所以它的继承数上的类不会被映射到一个大表中去。比如,我们来看下面的类继承树: </p><p> <tt class="literal">Animal-->Mammal-->Human</tt> </p><p> <tt class="literal">Animal-->Mammal-->Marsupial-->Kangaroo</tt> </p><p> 如果<span class="emphasis"><em>不</em></span>使用<tt class="literal">--abstract</tt>开关,<tt class="literal">Animal</tt>的所有子类都会被放到一个巨大的表中去,包含所有类的所有属性,还有一个用于分辨子类的字段。如果<tt class="literal">Mammal</tt>被标记成<tt class="literal">abstract</tt>,<tt class="literal">Human</tt>和<tt class="literal">Marsupial</tt>会被映射到不同的<tt class="literal"><class></tt>声明,并且会有各自单独的表。<tt class="literal">Kangaroo</tt>仍然会被认为是<tt class="literal">Marsupial</tt>的子类,除非<tt class="literal">Marsupial</tt>也标记为<tt class="literal">anstract</tt>的。 </p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="performance.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="example-parentchild.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">第 14 章 性能提升(Improving performance) </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 16 章 示例:父子关系(Parent Child Relationships)</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -