📄 tutorial.html
字号:
</p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="tutorial-firstapp-mapping"></a>2.2.2. 映射文件 </h3></div></div><div></div></div><p> Hibernate需要知道怎样去加载(load)和存储(store)我们的持久化类的对象。这里正是Hibernate映射文件(mapping file)发挥作用的地方。 映射文件告诉Hibernate它应该访问数据库里面的哪个表(table)和应该使用表里面的哪些字段(column)。 </p><p> 一个映射文件的基本结构看起来像这样: </p><pre class="programlisting"><?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>[...]</hibernate-mapping></pre><p> 注意Hibernate的DTD是非常复杂的。 你可以在你的编辑器或者IDE里面使用它来自动提示并完成(auto-completion)那些用来映射的XML元素(element)和属性(attribute)。 你也可以用你的文本编辑器打开DTD-这是最简单的方式来浏览所有元素和参数,查看它们的缺省值以及它们的注释,以得到一个整体的概观。 同时也要注意Hibernate不会从web上面获取DTD文件,虽然XML里面的URL也许会建议它这样做,但是Hibernate会首先查看你的程序的classpath。 DTD文件被包括在<tt class="literal">hibernate3.jar</tt>,同时也在Hibernate分发版的<tt class="literal">src/</tt>路径下。 </p><p> 在以后的例子里面,我们将通过省略DTD的声明来缩短代码长度。但是显然,在实际的程序中,DTD声明是必须的。 </p><p> 在两个<tt class="literal">hibernate-mapping</tt>标签(tag)中间, 我们包含了一个 <tt class="literal">class</tt>元素(element)。所有的持久性实体类(persistent entity classes)(再次声明, 这里也包括那些依赖类,就是那些次要的实体)都需要一个这样的映射,来映射到我们的SQL database。 </p><pre class="programlisting"><hibernate-mapping> <class name="Event" table="EVENTS"> </class></hibernate-mapping></pre><p> 我们到现在为止做的一切是告诉Hibernate怎样从数据库表(table)<tt class="literal">EVENTS</tt>里持久化和 加载<tt class="literal">Event</tt>类的对象,每个实例对应数据库里面的一行。现在我们将继续讨论有关唯一标识属性(unique identifier property)的映射。 另外,我们不希望去考虑怎样产生这个标识属性,我们将配置Hibernate的标识符生成策略(identifier generation strategy)来产生代用主键。 </p><pre class="programlisting"><hibernate-mapping> <class name="Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="increment"/> </id> </class></hibernate-mapping></pre><p> <tt class="literal">id</tt>元素是标识属性(identifer property)的声明, <tt class="literal">name="id"</tt> 声明了Java属性(property)的名字 - Hibernate将使用<tt class="literal">getId()</tt>和<tt class="literal">setId()</tt>来访问它。 字段参数(column attribute)则告诉Hibernate我们使用<tt class="literal">EVENTS</tt>表的哪个字段作为主键。 嵌套的<tt class="literal">generator</tt>元素指定了标识符的生成策略 - 在这里我们使用<tt class="literal">increment</tt>,这个是非常简单的在内存中直接生成数字的方法,多数用于测试(或教程)中。 Hibernate同时也支持使用数据库生成(database generated),全局唯一性(globally unique)和应用程序指定(application assigned) (或者你自己为任何已有策略所写的扩展) 这些方式来生成标识符。 </p><p> 最后我们还必须在映射文件里面包括需要持久化属性的声明。缺省的情况下,类里面的属性都被视为非持久化的: </p><pre class="programlisting"><hibernate-mapping> <class name="Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="increment"/> </id> <property name="date" type="timestamp" column="EVENT_DATE"/> <property name="title"/> </class></hibernate-mapping></pre><p> 和<tt class="literal">id</tt>元素类似,<tt class="literal">property</tt>元素的<tt class="literal">name</tt>参数 告诉Hibernate使用哪个getter和setter方法。 </p><p> 为什么<tt class="literal">date</tt>属性的映射包括<tt class="literal">column</tt>参数,但是<tt class="literal">title</tt>却没有? 当没有设定<tt class="literal">column</tt>参数的时候,Hibernate缺省使用属性名作为字段(column)名。对于<tt class="literal">title</tt>,这样工作得很好。 然而,<tt class="literal">date</tt>在多数的数据库里,是一个保留关键字,所以我们最好把它映射成另外一个名字。 </p><p> 下一件有趣的事情是<tt class="literal">title</tt>属性缺少一个<tt class="literal">type</tt>参数。 我们声明并使用在映射文件里面的type,并不像我们假想的那样,是Java data type, 同时也不是SQL database type。这些类型被称作<span class="emphasis"><em>Hibernate mapping types</em></span>, 它们把数据类型从Java转换到SQL data types。如果映射的参数没有设置的话,Hibernate也将尝试去确定正确的类型转换和它的映射类型。 在某些情况下这个自动检测(在Java class上使用反射机制)不会产生你所期待或者 需要的缺省值。这里有个例子是关于<tt class="literal">date</tt>属性。Hibernate无法知道这个属性应该被映射成下面这些类型中的哪一个: SQL <tt class="literal">date</tt>,<tt class="literal">timestamp</tt>,<tt class="literal">time</tt>。 我们通过声明属性映射<tt class="literal">timestamp</tt>来表示我们希望保存所有的关于日期和时间的信息。 </p><p> 这个映射文件(mapping file)应该被保存为<tt class="literal">Event.hbm.xml</tt>,和我们的<tt class="literal">Event</tt>Java 源文件放在同一个目录下。映射文件的名字可以是任意的,然而<tt class="literal">hbm.xml</tt>已经成为Hibernate开发者社区的习惯性约定。 现在目录应该看起来像这样: </p><pre class="programlisting">.+lib <Hibernate and third-party libraries>+src Event.java Event.hbm.xml</pre><p> 我们继续进行Hibernate的主要配置。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="tutorial-firstapp-configuration"></a>2.2.3. Hibernate配置 </h3></div></div><div></div></div><p> 我们现在已经有了一个持久化类和它的映射文件,是时候配置Hibernate了。在我们做这个之前,我们需要一个数据库。 HSQL DB,一个java-based内嵌式SQL数据库(in-memory SQL Database),可以从HSQL DB的网站上下载。 实际上,你仅仅需要下载/lib/目录中的<tt class="literal">hsqldb.jar</tt>。把这个文件放在开发文件夹的<tt class="literal">lib/</tt>目录里面。 </p><p> 在开发目录下面创建一个叫做<tt class="literal">data</tt>的目录 - 这个是HSQL DB存储它的数据文件的地方。 </p><p> Hibernate是你的程序里连接数据库的那个应用层,所以它需要连接用的信息。连接(connection)是通过一个也由我们配置的JDBC连接池(connection pool)。 Hibernate的分发版里面包括了一些open source的连接池,但是我们已经决定在这个教程里面使用内嵌式连接池。 如果你希望使用一个产品级的第三方连接池软件,你必须拷贝所需的库文件去你的classpath并使用不同的连接池设置。 </p><p> 为了配置Hibernate,我们可以使用一个简单的<tt class="literal">hibernate.properties</tt>文件, 或者一个稍微复杂的<tt class="literal">hibernate.cfg.xml</tt>,甚至可以完全使用程序来配置Hibernate。 多数用户喜欢使用XML配置文件: </p><pre class="programlisting"><?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -