📄 tutorial.html
字号:
</h3></div></div><div></div></div><p> Hibernate需要知道怎样去加载(load)和存储(store)持久化类的对象。这正是Hibernate映射文件发挥作用的地方。映射文件告诉Hibernate它,应该访问数据库(database)里面的哪个表(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里使用它来自动完成那些用来映射的XML元素(element)和属性(attribute)。你也可以在文本编辑器里打开DTD-这是最简单的方式来概览所有的元素和attribute,并查看它们的缺省值以及注释。注意Hibernate不会从web加载DTD文件,但它会首先在应用程序的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>元素。所有的持久化实体类(再次声明,或许接下来会有依赖类,就是那些次要的实体)都需要一个这样的映射,来把类对象映射到SQL数据库里的表。 </p><pre class="programlisting"><hibernate-mapping> <class name="events.Event" table="EVENTS"> </class></hibernate-mapping></pre><p> 到目前为止,我们告诉了Hibernate怎样把<tt class="literal">Events</tt>类的对象持久化到数据库的<tt class="literal">EVENTS</tt>表里,以及怎样从<tt class="literal">EVENTS</tt>表加载到<tt class="literal">Events</tt>类的对象。每个实例对应着数据库表中的一行。现在我们将继续讨论有关唯一标识符属性到数据库表的映射。另外,由于我们不关心怎样处理这个标识符,我们就配置由Hibernate的标识符生成策略来产生代理主键字段。 </p><pre class="programlisting"><hibernate-mapping> <class name="events.Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="native"/> </id> </class></hibernate-mapping></pre><p> <tt class="literal">id</tt>元素是标识符属性的声明,<tt class="literal">name="id"</tt> 声明了Java属性的名字 - Hibernate会使用<tt class="literal">getId()</tt>和<tt class="literal">setId()</tt>来访问它。 <tt class="literal">column</tt>属性则告诉Hibernate, 我们使用<tt class="literal">EVENTS</tt>表的哪个字段作为主键。嵌套的<tt class="literal">generator</tt>元素指定了标识符生成策略,在这里我们指定<tt class="literal">native</tt>,它根据已配置的数据库(方言)自动选择最佳的标识符生成策略。Hibernate支持由数据库生成,全局唯一性(globally unique)和应用程序指定(或者你自己为任何已有策略所写的扩展)这些策略来生成标识符。 </p><p> 最后我们在映射文件里面包含需要持久化属性的声明。默认情况下,类里面的属性都被视为非持久化的: </p><pre class="programlisting"><hibernate-mapping> <class name="events.Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="native"/> </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方法。在此例中,Hibernate会寻找<tt class="literal">getDate()/setDate()</tt>, 以及<tt class="literal">getTitle()/setTitle()</tt>。 </p><p> 为什么<tt class="literal">date</tt>属性的映射含有<tt class="literal">column</tt> attribute,而<tt class="literal">title</tt>却没有?当没有设定<tt class="literal">column</tt> attribute 的时候,Hibernate缺省地使用JavaBean的属性名作为字段名。对于<tt class="literal">title</tt>,这样工作得很好。然而,<tt class="literal">date</tt>在多数的数据库里,是一个保留关键字,所以我们最好把它映射成一个不同的名字。 </p><p> 另一有趣的事情是<tt class="literal">title</tt>属性缺少一个<tt class="literal">type</tt> attribute。我们在映射文件里声明并使用的类型,却不是我们期望的那样,是Java数据类型,同时也不是SQL数据库的数据类型。这些类型就是所谓的Hibernate 映射类型<span class="emphasis"><em>(mapping types)</em></span>,它们能把Java数据类型转换到SQL数据类型,反之亦然。再次重申,如果在映射文件中没有设置<tt class="literal">type</tt>属性的话,Hibernate会自己试着去确定正确的转换类型和它的映射类型。在某些情况下这个自动检测机制(在Java 类上使用反射机制)不会产生你所期待或需要的缺省值。<tt class="literal">date</tt>属性就是个很好的例子,Hibernate无法知道这个属性(<tt class="literal">java.util.Date</tt>类型的)应该被映射成:SQL <tt class="literal">date</tt>,或<tt class="literal">timestamp</tt>,还是<tt class="literal">time</tt> 字段。在此例中,把这个属性映射成<tt class="literal">timestamp</tt> 转换器,这样我们预留了日期和时间的全部信息。 </p><p> 应该把这个映射文件保存为<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 +events 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>1.2.3. Hibernate配置 </h3></div></div><div></div></div><p> 现在我们已经有了一个持久化类和它的映射文件,该是配置Hibernate的时候了。在此之前,我们需要一个数据库。 HSQL DB是种基于Java 的SQL数据库管理系统(DBMS),可以从HSQL DB的网站上下载。实际上,你只需下载的包中的<tt class="literal">hsqldb.jar</tt>文件,并把这个文件放在开发文件夹的<tt class="literal">lib/</tt>目录下即可。 </p><p> 在开发的根目录下创建一个<tt class="literal">data</tt>目录 - 这是HSQL DB存储数据文件的地方。此时在data目录中运行<tt class="literal">java -classpath lib/hsqldb.jar org.hsqldb.Server</tt>就可启动数据库。你可以在log中看到它的启动,及绑定到TCP/IP套结字,这正是我们的应用程序稍后会连接的地方。如果你希望在本例中运行一个全新的数据库,就在窗口中按下<tt class="literal">CTRL + C</tt>来关闭HSQL数据库,并删除<tt class="literal">data/</tt>目录下的所有文件,再重新启动HSQL数据库。 </p><p> Hibernate是你的应用程序里连接数据库的那层,所以它需要连接用的信息。连接(connection)是通过一个也由我们配置的JDBC连接池(connection pool)来完成的。Hibernate的发布包里包含了许多开源的(open source)连接池,但在我们例子中使用Hibernate内置的连接池。注意,如果你希望使用一个产品级(production-quality)的第三方连接池软件,你必须拷贝所需的库文件到你的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" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">org.hsqldb.jdbcDriver</property> <property name="connection.url">jdbc:hsqldb:hsql://localhost</property> <property name="connection.username">sa</property> <property name="connection.password"></property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -