﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Mike Cheers' Java World-文章分类-HIBERNATE - 符合Java习惯的关系数据库持久化</title><link>http://www.blogjava.net/mikecheers/category/29786.html</link><description>I can't give up</description><language>zh-cn</language><lastBuildDate>Sat, 01 Mar 2008 17:40:06 GMT</lastBuildDate><pubDate>Sat, 01 Mar 2008 17:40:06 GMT</pubDate><ttl>60</ttl><item><title>第 5 章 对象/关系数据库映射基础(Basic O/R Mapping)</title><link>http://www.blogjava.net/mikecheers/articles/183193.html</link><dc:creator>Mike Cheers</dc:creator><author>Mike Cheers</author><pubDate>Sat, 01 Mar 2008 15:06:00 GMT</pubDate><guid>http://www.blogjava.net/mikecheers/articles/183193.html</guid><wfw:comment>http://www.blogjava.net/mikecheers/comments/183193.html</wfw:comment><comments>http://www.blogjava.net/mikecheers/articles/183193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikecheers/comments/commentRss/183193.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikecheers/services/trackbacks/183193.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 第&nbsp;5&nbsp;章&nbsp;对象/关系数据库映射基础(Basic O/R Mapping)5.1.&nbsp;映射定义（Mapping declaration）对象和关系数据库之间的映射通常是用一个XML文档(XML document)来定义的。这个映射文档被设计为易读的， 并且可以手工修改。映射语言是以Java为中心，这意味着映射文档是按照持久化类的定义来创建的， 而非...&nbsp;&nbsp;<a href='http://www.blogjava.net/mikecheers/articles/183193.html'>阅读全文</a><img src ="http://www.blogjava.net/mikecheers/aggbug/183193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikecheers/" target="_blank">Mike Cheers</a> 2008-03-01 23:06 <a href="http://www.blogjava.net/mikecheers/articles/183193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第 4 章 持久化类(Persistent Classes)</title><link>http://www.blogjava.net/mikecheers/articles/183189.html</link><dc:creator>Mike Cheers</dc:creator><author>Mike Cheers</author><pubDate>Sat, 01 Mar 2008 14:54:00 GMT</pubDate><guid>http://www.blogjava.net/mikecheers/articles/183189.html</guid><wfw:comment>http://www.blogjava.net/mikecheers/comments/183189.html</wfw:comment><comments>http://www.blogjava.net/mikecheers/articles/183189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikecheers/comments/commentRss/183189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikecheers/services/trackbacks/183189.html</trackback:ping><description><![CDATA[<h2 class="title"><a name="persistent-classes"></a>第&nbsp;4&nbsp;章&nbsp;持久化类(Persistent Classes)</h2>
<p>在应用程序中，用来实现业务问题实体的（如，在电子商务应用程序中的Customer和Order） 类就是持久化类。不能认为所有的持久化类的实例都是持久的状态——一个实例的状态也可能 是瞬时的或脱管的。 </p>
<p>如果这些持久化类遵循一些简单的规则，Hibernate能够工作得最好，这些规则被认为是， 简单传统Java对象(POJO:Plain Old Java Object)编程模型。但是这些规则没有一个是必需的。 实际上，Hibernate3对于你的持久化类几乎不做任何设想。你可以用其他的方法来表达领域模型： 比如，使用<tt class="literal">Map</tt>实例的树型结构。 </p>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="persistent-classes-pojo"></a>4.1.&nbsp;一个简单的POJO例子</h2>
<p>大多数Java程序需要用一个持久化类来表示猫科动物。 </p>
<pre class="programlisting">package eg;
import java.util.Set;
import java.util.Date;
public class Cat {
private Long id; // identifier
private Date birthdate;
private Color color;
private char sex;
private float weight;
private int litterId;
private Cat mother;
private Set kittens = new HashSet();
private void setId(Long id) {
this.id=id;
}
public Long getId() {
return id;
}
void setBirthdate(Date date) {
birthdate = date;
}
public Date getBirthdate() {
return birthdate;
}
void setWeight(float weight) {
this.weight = weight;
}
public float getWeight() {
return weight;
}
public Color getColor() {
return color;
}
void setColor(Color color) {
this.color = color;
}
void setSex(char sex) {
this.sex=sex;
}
public char getSex() {
return sex;
}
void setLitterId(int id) {
this.litterId = id;
}
public int getLitterId() {
return litterId;
}
void setMother(Cat mother) {
this.mother = mother;
}
public Cat getMother() {
return mother;
}
void setKittens(Set kittens) {
this.kittens = kittens;
}
public Set getKittens() {
return kittens;
}
// addKitten not needed by Hibernate
public void addKitten(Cat kitten) {
kitten.setMother(this);
kitten.setLitterId( kittens.size() );
kittens.add(kitten);
}
}</pre>
<p>There are four main rules to follow here: </p>
<p>这里要遵循四条主要的规则： </p>
<h3 class="title"><a name="persistent-classes-pojo-accessors"></a>4.1.1.&nbsp;为持久化字段声明访问器(accessors)和是否可变的标志(mutators)</h3>
<p><tt class="literal">Cat</tt>为它的所有持久化字段声明了访问方法。很多其他ORM工具直接对 实例变量进行持久化。我们相信从持久化机制中分离这种实现细节要好得多。 Hibernate持久化JavaBeans风格的属性，认可如下形式的方法名： <tt class="literal">getFoo</tt>, <tt class="literal">isFoo</tt> 和 <tt class="literal">setFoo</tt>。 如果需要，你总是可以切换特定的属性的指示字段的访问方法。 </p>
<p>属性<span class="emphasis"><em>不需要</em></span>要声明为public的。Hibernate默认使用 <tt class="literal">protected</tt>或<tt class="literal">private</tt>的get/set方法对， 对属性进行持久化。 </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="persistent-classes-pojo-constructor"></a>4.1.2.&nbsp;实现一个默认的（即无参数的）构造方法（constructor）</h3>
<p><tt class="literal">Cat</tt>有一个无参数的构造方法。所有的持久化类都必须有一个 默认的构造方法（可以不是public的），这样的话Hibernate就可以使用 <tt class="literal">Constructor.newInstance()</tt>来实例化它们。 我们建议，在Hibernate中，为了运行期代理的生成，构造方法至少是 <span class="emphasis"><em>包(package)</em></span>内可见的。 </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="persistent-classes-pojo-identifier"></a>4.1.3.&nbsp;提供一个标识属性（identifier property）（可选） </h3>
<p><tt class="literal">Cat</tt>有一个属性叫做<tt class="literal">id</tt>。这个属性映射数据库表的主 键字段。这个属性可以叫任何名字，其类型可以是任何的原始类型、原始类型的包装类型、 <tt class="literal">java.lang.String</tt> 或者是 <tt class="literal">java.util.Date</tt>。 （如果你的老式数据库表有联合主键，你甚至可以用一个用户自定义的类，该类拥有这些类型 的属性。参见后面的关于联合标识符的章节。） </p>
<p>标识符属性是可选的。可以不用管它，让Hibernate内部来追踪对象的识别。 不推荐使用这个属性。 </p>
<p>实际上，一些功能只对那些声明了标识符属性的类起作用： </p>
<div class="itemizedlist">
<ul type="disc" compact>
    <li>
    <p>托管对象的传播性重新（和session）关联（级联更新或级联合并） ——参阅 <a title="10.11.&nbsp;传播性持久化(transitive persistence)" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/objectstate.html#objectstate-transitive">第&nbsp;10.11&nbsp;节 &#8220;传播性持久化(transitive persistence)&#8221;</a> </p>
    <li>
    <p><tt class="literal">Session.saveOrUpdate()</tt> </p>
    <li>
    <p><tt class="literal">Session.merge()</tt> </p>
    </li>
</ul>
</div>
<p>我们建议你对持久化类声明命名一致的标识属性。我们还建议你使用一 个可以为空（也就是说，不是原始类型）的类型。 </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="persistent-classes-pojo-final"></a>4.1.4.&nbsp;使用非final的类 (可选)</h3>
<p><span class="emphasis"><em>代理（proxies）</em></span>是Hibernate的一个重要的功能，它依赖的条件是，持久 化类或者是非final的，或者是实现了一个所有方法都声明为public的接口。 </p>
<p>你可以用Hibernate持久化一个没有实现任何接口的<tt class="literal">final</tt>类，但是你 不能使用代理来延迟关联加载，这会限制你进行性能优化的选择。 </p>
<p>你也应该避免在非final类中声明 <tt class="literal">public final</tt>的方法。如果你想使用一 个有<tt class="literal">public final</tt>方法的类，你必须通过设置<tt class="literal">lazy="false"</tt> 来明确的禁用代理。 </p>
</div>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="persistent-classes-inheritance"></a>4.2.&nbsp;实现继承（Inheritance）</h2>
<p>子类也必须遵守第一条和第二条规则。它从超类<tt class="literal">Cat</tt>继承了标识属性。 </p>
<pre class="programlisting">package eg;
public class DomesticCat extends Cat {
private String name;
public String getName() {
return name;
}
protected void setName(String name) {
this.name=name;
}
}</pre>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="persistent-classes-equalshashcode"></a>4.3.&nbsp;实现<tt class="literal">equals()</tt>和<tt class="literal">hashCode()</tt></h2>
<p>如果你有如下需求，你必须重载 <tt class="literal">equals()</tt> 和 <tt class="literal">hashCode()</tt>方法： </p>
<div class="itemizedlist">
<ul type="disc" compact>
    <li>
    <p>想把持久类的实例放入<tt class="literal">Set</tt>中（当表示多值关联时，推荐这么做） </p>
    <li>
    <p>想重用脱管实例 </p>
    </li>
</ul>
</div>
<p>Hibernate保证，持久化标识（数据库的行）和仅在特定会话范围内的Java标识是等值的。因此，一旦 我们混合了从不同会话中获取的实例，如果我们希望<tt class="literal">Set</tt>有明确的语义，我们必 须实现<tt class="literal">equals()</tt> 和<tt class="literal">hashCode()</tt>。 </p>
<p>实现<tt class="literal">equals()</tt>/<tt class="literal">hashCode()</tt>最显而易见的方法是比较两个对象 标识符的值。如果值相同，则两个对象对应于数据库的同一行，因此它们是相等的（如果都被添加到 <tt class="literal">Set</tt>，则在<tt class="literal">Set</tt>中只有一个元素）。不幸的是，对生成的标识不能 使用这种方法。Hibernate仅对那些持久化对象赋标识值，一个新创建的实例将不会有任何标识值。此外， 如果一个实例没有被保存(unsaved)，并且在一个<tt class="literal">Set</tt>中，保存它将会给这个对象 赋一个标识值。如果<tt class="literal">equals()</tt> 和 <tt class="literal">hashCode()</tt>是基于标识值 实现的，则其哈希码将会改变，违反<tt class="literal">Set</tt>的契约。建议去Hibernate的站点看关于这个 问题的全部讨论。注意，这不是一个Hibernate问题，而是一般的Java对象标识和相等的语义问题。 </p>
<p>我们建议使用<span class="emphasis"><em>业务键值相等(Business key equality)</em></span>来实现<tt class="literal">equals()</tt> 和 <tt class="literal">hashCode()</tt>。业务键值相等的意思是，<tt class="literal">equals()</tt>方法 仅仅比较来自业务键的属性，一个业务键将标识在真实世界里（一个<span class="emphasis"><em>天生的</em></span>候选键） 的实例。 </p>
<pre class="programlisting">public class Cat {
...
public boolean equals(Object other) {
if (this == other) return true;
if ( !(other instanceof Cat) ) return false;
final Cat cat = (Cat) other;
if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
if ( !cat.getMother().equals( getMother() ) ) return false;
return true;
}
public int hashCode() {
int result;
result = getMother().hashCode();
result = 29 * result + getLitterId();
return result;
}
}</pre>
<p>注意，业务键不必是象数据库的主键那样是固定不变的（参见<a title="11.1.3.&nbsp;关注对象标识(Considering object identity)" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/transactions.html#transactions-basics-identity">第&nbsp;11.1.3&nbsp;节 &#8220;关注对象标识(Considering object identity)&#8221;</a>）。 对业务键而言，不可变或唯一的属性是好的候选。 </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="persistent-classes-dynamicmodels"></a>4.4.&nbsp;动态模型(Dynamic models)</h2>
<p><span class="emphasis"><em>注意，以下特性在当前是基于实验考虑的，可能会在将来改变。</em></span> </p>
<p>运行期的持久化实体没有必要象POJO类或JavaBean对象一样表示。Hibernate也支持动态模型 （在运行期使用<tt class="literal">Map</tt>的<tt class="literal">Map</tt>）和象DOM4J的树模型那 样的实体表示。使用这种方法，你不用写持久化类，只写映射文件就行了。 </p>
<p>Hibernate默认工作在普通POJO模式。你可以使用配置选项<tt class="literal">default_entity_mode</tt>， 对特定的<tt class="literal">SessionFactory</tt>，设置一个默认的实体表示模式。 （参见<a title="表&nbsp;3.3.&nbsp;&#10;                Hibernate配置属性&#10;            " href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/session-configuration.html#configuration-optional-properties">表&nbsp;3.3 &#8220; Hibernate配置属性 &#8221;</a>。） </p>
<p>下面是用<tt class="literal">Map</tt>来表示的例子。首先，在映射文件中，要声明 <tt class="literal">entity-name</tt>来代替（或外加）一个类名。 </p>
<pre class="programlisting">&lt;hibernate-mapping&gt;
&lt;class entity-name="Customer"&gt;
&lt;id name="id"
type="long"
column="ID"&gt;
&lt;generator class="sequence"/&gt;
&lt;/id&gt;
&lt;property name="name"
column="NAME"
type="string"/&gt;
&lt;property name="address"
column="ADDRESS"
type="string"/&gt;
&lt;many-to-one name="organization"
column="ORGANIZATION_ID"
class="Organization"/&gt;
&lt;bag name="orders"
inverse="true"
lazy="false"
cascade="all"&gt;
&lt;key column="CUSTOMER_ID"/&gt;
&lt;one-to-many class="Order"/&gt;
&lt;/bag&gt;
&lt;/class&gt;
&lt;/hibernate-mapping&gt;</pre>
<p>注意，虽然是用目标类名来声明关联的，但是关联的目标类型除了是POJO之外，也可以 是一个动态的实体。 </p>
<p>在使用<tt class="literal">dynamic-map</tt>为<tt class="literal">SessionFactory</tt> 设置了默认的实体模式之后，可以在运行期使用<tt class="literal">Map</tt>的 <tt class="literal">Map</tt>。 </p>
<pre class="programlisting">Session s = openSession();
Transaction tx = s.beginTransaction();
Session s = openSession();
// Create a customer
Map david = new HashMap();
david.put("name", "David");
// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");
// Link both
david.put("organization", foobar);
// Save both
s.save("Customer", david);
s.save("Organization", foobar);
tx.commit();
s.close();</pre>
<p>动态映射的好处是，使原型在不需要实体类实现的情况下，快速转变时间。然而，你无法进行 编译期的类型检查，并可能由此会处理很多的运行期异常。幸亏有了Hibernate映射，它使得数 据库的schema能容易的规格化和合理化，并允许稍后添加正确的领域模型的最新实现。 </p>
<p>实体表示模式也能在每个<tt class="literal">Session</tt>的基础上设置： </p>
<pre class="programlisting">Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
// Create a customer
Map david = new HashMap();
david.put("name", "David");
dynamicSession.save("Customer", david);
...
dynamicSession.flush();
dynamicSession.close()
...
// Continue on pojoSession
</pre>
<p>请注意，用<tt class="literal">EntityMode</tt>调用<tt class="literal">getSession()</tt>是在 <tt class="literal">Session</tt>的API中，而不是<tt class="literal">SessionFactory</tt>。 这样，新的<tt class="literal">Session</tt>共享底层的JDBC连接，事务，和其他的上下文信 息。这意味着，你不需要在第二个<tt class="literal">Session</tt>中调用 <tt class="literal">flush()</tt>和<tt class="literal">close()</tt>，同样的，把事务和连接的处理 交给原来的工作单元。 </p>
<p>关于XML表示能力的更多信息可以在<a title="第&nbsp;18&nbsp;章&nbsp;XML映射" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/xml.html">第&nbsp;18&nbsp;章 <em>XML映射</em></a>中找到。 </p>
</div>
<p>TODO：在property和proxy的包里，用户扩展文件框架。</p><img src ="http://www.blogjava.net/mikecheers/aggbug/183189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikecheers/" target="_blank">Mike Cheers</a> 2008-03-01 22:54 <a href="http://www.blogjava.net/mikecheers/articles/183189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第 3 章  配置</title><link>http://www.blogjava.net/mikecheers/articles/182908.html</link><dc:creator>Mike Cheers</dc:creator><author>Mike Cheers</author><pubDate>Fri, 29 Feb 2008 06:07:00 GMT</pubDate><guid>http://www.blogjava.net/mikecheers/articles/182908.html</guid><wfw:comment>http://www.blogjava.net/mikecheers/comments/182908.html</wfw:comment><comments>http://www.blogjava.net/mikecheers/articles/182908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikecheers/comments/commentRss/182908.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikecheers/services/trackbacks/182908.html</trackback:ping><description><![CDATA[
<h2 class="title">第&nbsp;3&nbsp;章&nbsp; 配置 </h2>
<p>由于Hibernate是为了能在各种不同环境下工作而设计的, 因此存在着大量的配置参数. 幸运的是多数配置参数都 有比较直观的默认值, 并有随Hibernate一同分发的配置样例<tt class="literal">hibernate.properties</tt> (位于<tt class="literal">etc/</tt>)来展示各种配置选项. 所需做的仅仅是将这个样例文件复制到类路径 (classpath)下做一些自定义的修改. </p>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="configuration-programmatic"></a>3.1.&nbsp; 可编程的配置方式 </h2>
<p>一个<tt class="literal">org.hibernate.cfg.Configuration</tt>实例代表了一个应用程序中Java类型 到SQL数据库映射的完整集合. <tt class="literal">Configuration</tt>被用来构建一个(不可变的 (immutable))<tt class="literal">SessionFactory</tt>. 映射定义则由不同的XML映射定义文件编译而来. </p>
<p>你可以直接实例化<tt class="literal">Configuration</tt>来获取一个实例，并为它指定XML映射定义 文件. 如果映射定 义文件在类路径(classpath)中, 请使用<tt class="literal">addResource()</tt>: </p>
<pre class="programlisting">Configuration cfg = new Configuration()
.addResource("Item.hbm.xml")
.addResource("Bid.hbm.xml");</pre>
<p>一个替代方法（有时是更好的选择）是，指定被映射的类，让Hibernate帮你寻找映射定义文件: </p>
<pre class="programlisting">Configuration cfg = new Configuration()
.addClass(org.hibernate.auction.Item.class)
.addClass(org.hibernate.auction.Bid.class);</pre>
<p>Hibernate将会在类路径(classpath)中寻找名字为 <tt class="literal">/org/hibernate/auction/Item.hbm.xml</tt>和 <tt class="literal">/org/hibernate/auction/Bid.hbm.xml</tt>映射定义文件. 这种方式消除了任何对文件名的硬编码(hardcoded). </p>
<p><tt class="literal">Configuration</tt>也允许你指定配置属性: </p>
<pre class="programlisting">Configuration cfg = new Configuration()
.addClass(org.hibernate.auction.Item.class)
.addClass(org.hibernate.auction.Bid.class)
.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
.setProperty("hibernate.order_updates", "true");</pre>
<p>当然这不是唯一的传递Hibernate配置属性的方式, 其他可选方式还包括: </p>
<div class="orderedlist">
<ol type="1" compact>
    <li>
    <p>传一个<tt class="literal">java.util.Properties</tt>实例给 <tt class="literal">Configuration.setProperties()</tt>. </p>
    </li>
    <li>
    <p>将<tt class="literal">hibernate.properties</tt>放置在类路径(classpath)的根目录下 (root directory). </p>
    </li>
    <li>
    <p>通过<tt class="literal">java -Dproperty=value</tt>来设置系统 (<tt class="literal">System</tt>)属性. </p>
    </li>
    <li>
    <p>在<tt class="literal">hibernate.cfg.xml</tt>中加入元素 <tt class="literal">&lt;property&gt;</tt> (稍后讨论). </p>
    </li>
</ol>
</div>
<p>如果想尽快体验Hbernate, <tt class="literal">hibernate.properties</tt>是最简单的方式. </p>
<p><tt class="literal">Configuration</tt>实例是一个启动期间（startup-time）的对象, 一旦<tt class="literal">SessionFactory</tt>创建完成它就被丢弃了. </p>
</div>
<div class="sect1" lang="zh-cn">

<h2 class="title" style="clear: both"><a name="configuration-sessionfactory"></a>3.2.&nbsp; 获得SessionFactory </h2>
<p>当所有映射定义被<tt class="literal">Configuration</tt>解析后, 应用程序必须获得一个用于构造<tt class="literal">Session</tt>实例的工厂. 这个工厂将被应用程序的所有线程共享: </p>
<pre class="programlisting">SessionFactory sessions = cfg.buildSessionFactory();</pre>
<p>Hibernate允许你的应用程序创建多个<tt class="literal">SessionFactory</tt>实例. 这对 使用多个数据库的应用来说很有用. </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="configuration-hibernatejdbc"></a>3.3.&nbsp; JDBC连接 </h2>
<p>通常你希望<tt class="literal">SessionFactory</tt>来为你创建和缓存(pool)JDBC连接. 如果你采用这种方式, 只需要如下例所示那样，打开一个<tt class="literal">Session</tt>: </p>
<pre class="programlisting">Session session = sessions.openSession(); // open a new Session</pre>
<p>一旦你需要进行数据访问时, 就会从连接池(connection pool)获得一个JDBC连接. </p>
<p>为了使这种方式工作起来, 我们需要向Hibernate传递一些JDBC连接的属性. 所有Hibernate属性的名字和语义都在<tt class="literal">org.hibernate.cfg.Environment</tt>中定义. 我们现在将描述JDBC连接配置中最重要的设置. </p>
<p>如果你设置如下属性，Hibernate将使用<tt class="literal">java.sql.DriverManager</tt>来获得(和缓存)JDBC连接 : </p>
<div class="table"><a name="d0e1176"></a>
<p class="title"><strong>表&nbsp;3.1.&nbsp; Hibernate JDBC属性 </strong></p>
<table summary="                Hibernate JDBC属性&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>属性名 </th>
            <th>用途 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">hibernate.connection.driver_class</tt></td>
            <td><span class="emphasis"><em>jdbc驱动类</em></span></td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.url</tt></td>
            <td><span class="emphasis"><em>jdbc URL</em></span></td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.username</tt></td>
            <td><span class="emphasis"><em>数据库用户</em></span></td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.password</tt></td>
            <td><span class="emphasis"><em>数据库用户密码</em></span></td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.pool_size</tt></td>
            <td><span class="emphasis"><em>连接池容量上限数目</em></span></td>
        </tr>
    </tbody>
</table>
</div>
<p>但Hibernate自带的连接池算法相当不成熟. 它只是为了让你快些上手<span class="emphasis"><em>，不适合用于产品系统</em></span>或性能测试中。 出于最佳性能和稳定性考虑你应该使用第三方的连接池。只需要连接池的特定设置替换 <tt class="literal">hibernate.connection.pool_size</tt>。这将关闭Hibernate自带的连接池. 例如, 你可能会想用C3P0. </p>
<p>C3P0是一个随Hibernate一同分发的开源的JDBC连接池, 它位于<tt class="literal">lib</tt>目录下。 如果你设置了<tt class="literal">hibernate.c3p0.*</tt>相关的属性, Hibernate将使用 <tt class="literal">C3P0ConnectionProvider</tt>来缓存JDBC连接. 如果你更原意使用Proxool, 请参考发 行包中的<tt class="literal">hibernate.properties</tt>并到Hibernate网站获取更多的信息. </p>
<p>这是一个使用C3P0的<tt class="literal">hibernate.properties</tt>样例文件: </p>
<a name="c3p0-configuration"></a>
<pre class="programlisting">hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect</pre>
<p>为了能在应用程序服务器(application server)中使用Hibernate, 你应当总是将Hibernate 配置成注册在JNDI中的<tt class="literal">Datasource</tt>处获得连接，你至少需要设置下列属性中的一个: </p>
<div class="table"><a name="d0e1258"></a>
<p class="title"><strong>表&nbsp;3.2.&nbsp; Hibernate数据源属性 </strong></p>
<table summary="                Hibernate数据源属性&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>属性名 </th>
            <th>用途 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">hibernate.connection.datasource</tt></td>
            <td><span class="emphasis"><em>数据源JNDI名字</em></span></td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jndi.url</tt></td>
            <td><span class="emphasis"><em>JNDI提供者的URL</em></span> (可选) </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jndi.class</tt></td>
            <td><span class="emphasis"><em>JNDI <tt class="literal">InitialContextFactory</tt>类</em></span> (可选) </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.username</tt></td>
            <td><span class="emphasis"><em>数据库用户</em></span> (可选) </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.password</tt></td>
            <td><span class="emphasis"><em>数据库用户密码</em></span> (可选) </td>
        </tr>
    </tbody>
</table>
</div>
<p>这里有一个使用应用程序服务器JNDI数据源的<tt class="literal">hibernate.properties</tt>样例文件: </p>
<pre class="programlisting">hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect</pre>
<p>从JNDI数据源获得的JDBC连接将自动参与应用程序服务器中容器管理的事务(container-managed transactions)中去. </p>
<p>任何连接(connection)配置属性的属性名要以"<tt class="literal">hibernate.connnection</tt>"前缀开头. 例如, 你可能会使用<tt class="literal">hibernate.connection.charSet</tt>来指定<tt class="literal">charSet</tt>. </p>
<p>通过实现<tt class="literal">org.hibernate.connection.ConnectionProvider</tt>接口，你可以定义属于 你自己的获得JDBC连接的插件策略。通过设置<tt class="literal">hibernate.connection.provider_class</tt>， 你可以选择一个自定义的实现. </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">3.4.&nbsp; 可选的配置属性 </h2>

<p>有大量属性能用来控制Hibernate在运行期的行为. 它们都是可选的, 并拥有适当的默认值. </p>
<p><span class="emphasis"><em>警告: 其中一些属性是"系统级(system-level)的".</em></span> 系统级属性可以通过<tt class="literal">java -Dproperty=value</tt>或 <tt class="literal">hibernate.properties</tt>来设置, 而<span class="emphasis"><em>不能</em></span>用上面描述的其他方法来设置. </p>
<div class="table"><a name="configuration-optional-properties"></a>
<p class="title"><strong>表&nbsp;3.3.&nbsp; Hibernate配置属性 </strong></p>
<table summary="                Hibernate配置属性&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>属性名 </th>
            <th>用途 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">hibernate.dialect</tt></td>
            <td>一个Hibernate <tt class="literal">Dialect</tt>类名允许Hibernate针对特定的关系数据库生成优化的SQL.
            <p><span class="strong">取值</span> <tt class="literal">full.classname.of.Dialect</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.show_sql</tt></td>
            <td>输出所有SQL语句到控制台.
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.default_schema</tt></td>
            <td>在生成的SQL中, 将给定的schema/tablespace附加于非全限定名的表名上.
            <p><span class="strong">取值</span> <tt class="literal">SCHEMA_NAME</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.default_catalog</tt></td>
            <td>在生成的SQL中, 将给定的catalog附加于没全限定名的表名上.
            <p><span class="strong">取值</span> <tt class="literal">CATALOG_NAME</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.session_factory_name</tt></td>
            <td><tt class="literal">SessionFactory</tt>创建后，将自动使用这个名字绑定到JNDI中.
            <p><span class="strong">取值</span> <tt class="literal">jndi/composite/name</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.max_fetch_depth</tt></td>
            <td>为单向关联(一对一, 多对一)的外连接抓取（outer join fetch）树设置最大深度. 值为<tt class="literal">0</tt>意味着将关闭默认的外连接抓取.
            <p><span class="strong">取值</span> 建议在<tt class="literal">0</tt>到<tt class="literal">3</tt>之间取值 </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.default_batch_fetch_size</tt></td>
            <td>为Hibernate关联的批量抓取设置默认数量.
            <p><span class="strong">取值</span> 建议的取值为<tt class="literal">4</tt>, <tt class="literal">8</tt>, 和<tt class="literal">16</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.default_entity_mode</tt></td>
            <td>为由这个<tt class="literal">SessionFactory</tt>打开的所有Session指定默认的实体表现模式.
            <p><span class="strong">取值</span> <tt class="literal">dynamic-map</tt>, <tt class="literal">dom4j</tt>, <tt class="literal">pojo</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.order_updates</tt></td>
            <td>强制Hibernate按照被更新数据的主键，为SQL更新排序。这么做将减少在高并发系统中事务的死锁。
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.generate_statistics</tt></td>
            <td>如果开启, Hibernate将收集有助于性能调节的统计数据.
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.use_identifer_rollback</tt></td>
            <td>如果开启, 在对象被删除时生成的标识属性将被重设为默认值.
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.use_sql_comments</tt></td>
            <td>如果开启, Hibernate将在SQL中生成有助于调试的注释信息, 默认值为<tt class="literal">false</tt>.
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div class="table"><a name="configuration-jdbc-properties"></a>
<p class="title"><strong>表&nbsp;3.4.&nbsp; Hibernate JDBC和连接(connection)属性 </strong></p>
<table summary="                Hibernate JDBC和连接(connection)属性&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>属性名 </th>
            <th>用途 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">hibernate.jdbc.fetch_size</tt></td>
            <td>非零值，指定JDBC抓取数量的大小 (调用<tt class="literal">Statement.setFetchSize()</tt>). </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jdbc.batch_size</tt></td>
            <td>非零值，允许Hibernate使用JDBC2的批量更新.
            <p><span class="strong">取值</span> 建议取<tt class="literal">5</tt>到<tt class="literal">30</tt>之间的值 </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jdbc.batch_versioned_data</tt></td>
            <td>如果你想让你的JDBC驱动从<tt class="literal">executeBatch()</tt>返回正确的行计数 , 那么将此属性设为<tt class="literal">true</tt>(开启这个选项通常是安全的). 同时，Hibernate将为自动版本化的数据使用批量DML. 默认值为<tt class="literal">false</tt>.
            <p><span class="strong">eg.</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jdbc.factory_class</tt></td>
            <td>选择一个自定义的<tt class="literal">Batcher</tt>. 多数应用程序不需要这个配置属性.
            <p><span class="strong">eg.</span> <tt class="literal">classname.of.Batcher</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jdbc.use_scrollable_resultset</tt></td>
            <td>允许Hibernate使用JDBC2的可滚动结果集. 只有在使用用户提供的JDBC连接时，这个选项才是必要的, 否则Hibernate会使用连接的元数据.
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jdbc.use_streams_for_binary</tt></td>
            <td>在JDBC读写<tt class="literal">binary (二进制)</tt>或<tt class="literal">serializable (可序列化)</tt> 的类型时使用流(stream)(系统级属性).
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jdbc.use_get_generated_keys</tt></td>
            <td>在数据插入数据库之后，允许使用JDBC3 <tt class="literal">PreparedStatement.getGeneratedKeys()</tt> 来获取数据库生成的key(键)。需要JDBC3+驱动和JRE1.4+, 如果你的数据库驱动在使用Hibernate的标 识生成器时遇到问题，请将此值设为false. 默认情况下将使用连接的元数据来判定驱动的能力.
            <p><span class="strong">取值</span> <tt class="literal">true|false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.provider_class</tt></td>
            <td>自定义<tt class="literal">ConnectionProvider</tt>的类名, 此类用来向Hibernate提供JDBC连接.
            <p><span class="strong">取值</span> <tt class="literal">classname.of.ConnectionProvider</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.isolation</tt></td>
            <td>设置JDBC事务隔离级别. 查看<tt class="literal">java.sql.Connection</tt>来了解各个值的具体意义, 但请注意多数数据库都不支持所有的隔离级别.
            <p><span class="strong">取值</span> <tt class="literal">1, 2, 4, 8</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.autocommit</tt></td>
            <td>允许被缓存的JDBC连接开启自动提交(autocommit) (不建议).
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.release_mode</tt></td>
            <td>指定Hibernate在何时释放JDBC连接. 默认情况下,直到Session被显式关闭或被断开连接时,才会释放JDBC连接. 对于应用程序服务器的JTA数据源, 你应当使用<tt class="literal">after_statement</tt>, 这样在每次JDBC调用后，都会主动的释放连接. 对于非JTA的连接, 使用<tt class="literal">after_transaction</tt>在每个事务结束时释放连接是合理的. <tt class="literal">auto</tt>将为JTA和CMT事务策略选择<tt class="literal">after_statement</tt>, 为JDBC事务策略选择<tt class="literal">after_transaction</tt>.
            <p><span class="strong">取值</span> <tt class="literal">on_close</tt> | <tt class="literal">after_transaction</tt> | <tt class="literal">after_statement</tt> | <tt class="literal">auto</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.connection.<span class="emphasis"><em>&lt;propertyName&gt;</em></span></tt></td>
            <td>将JDBC属性<tt class="literal">propertyName</tt>传递到<tt class="literal">DriverManager.getConnection()</tt>中去. </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.jndi.<span class="emphasis"><em>&lt;propertyName&gt;</em></span></tt></td>
            <td>将属性<tt class="literal">propertyName</tt>传递到JNDI <tt class="literal">InitialContextFactory</tt>中去. </td>
        </tr>
    </tbody>
</table>
</div>
<div class="table"><a name="configuration-cache-properties"></a>
<p class="title"><strong>表&nbsp;3.5.&nbsp; Hibernate缓存属性 </strong></p>
<table summary="                Hibernate缓存属性&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>属性名 </th>
            <th>用途 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">hibernate.cache.provider_class</tt></td>
            <td>自定义的<tt class="literal">CacheProvider</tt>的类名.
            <p><span class="strong">取值</span> <tt class="literal">classname.of.CacheProvider</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.cache.use_minimal_puts</tt></td>
            <td>以频繁的读操作为代价, 优化二级缓存来最小化写操作. 在Hibernate3中，这个设置对的集群缓存非常有用, 对集群缓存的实现而言，默认是开启的.
            <p><span class="strong">取值</span> <tt class="literal">true|false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.cache.use_query_cache</tt></td>
            <td>允许查询缓存, 个别查询仍然需要被设置为可缓存的.
            <p><span class="strong">取值</span> <tt class="literal">true|false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.cache.use_second_level_cache</tt></td>
            <td>能用来完全禁止使用二级缓存. 对那些在类的映射定义中指定<tt class="literal">&lt;cache&gt;</tt>的类，会默认开启二级缓存.
            <p><span class="strong">取值</span> <tt class="literal">true|false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.cache.query_cache_factory</tt></td>
            <td>自定义的实现<tt class="literal">QueryCache</tt>接口的类名, 默认为内建的<tt class="literal">StandardQueryCache</tt>.
            <p><span class="strong">取值</span> <tt class="literal">classname.of.QueryCache</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.cache.region_prefix</tt></td>
            <td>二级缓存区域名的前缀.
            <p><span class="strong">取值</span> <tt class="literal">prefix</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.cache.use_structured_entries</tt></td>
            <td>强制Hibernate以更人性化的格式将数据存入二级缓存.
            <p><span class="strong">取值</span> <tt class="literal">true|false</tt> </p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div class="table"><a name="configuration-transaction-properties"></a>
<p class="title"><strong>表&nbsp;3.6.&nbsp; Hibernate事务属性 </strong></p>
<table summary="                Hibernate事务属性&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>属性名 </th>
            <th>用途 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">hibernate.transaction.factory_class</tt></td>
            <td>一个<tt class="literal">TransactionFactory</tt>的类名, 用于Hibernate <tt class="literal">Transaction</tt> API (默认为<tt class="literal">JDBCTransactionFactory</tt>).
            <p><span class="strong">取值</span> <tt class="literal">classname.of.TransactionFactory</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">jta.UserTransaction</tt></td>
            <td>一个JNDI名字，被<tt class="literal">JTATransactionFactory</tt>用来从应用服务器获取JTA <tt class="literal">UserTransaction</tt>.
            <p><span class="strong">取值</span> <tt class="literal">jndi/composite/name</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.transaction.manager_lookup_class</tt></td>
            <td>一个<tt class="literal">TransactionManagerLookup</tt>的类名 - 当使用JVM级缓存，或在JTA环境中使用hilo生成器的时候需要该类.
            <p><span class="strong">取值</span> <tt class="literal">classname.of.TransactionManagerLookup</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.transaction.flush_before_completion</tt></td>
            <td>如果开启, session在事务完成后将被自动清洗(flush). (在Hibernate和CMT一起使用时很有用.)
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.transaction.auto_close_session</tt></td>
            <td>如果开启, session在事务完成前将被自动关闭. (在Hibernate和CMT一起使用时很有用.)
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div class="table"><a name="configuration-misc-properties"></a>
<p class="title"><strong>表&nbsp;3.7.&nbsp; 其他属性 </strong></p>
<table summary="                其他属性&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>属性名 </th>
            <th>用途 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">hibernate.query.factory_class</tt></td>
            <td>选择HQL解析器的实现.
            <p><span class="strong">取值</span> <tt class="literal">org.hibernate.hql.ast.ASTQueryTranslatorFactory</tt> or <tt class="literal">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.query.substitutions</tt></td>
            <td>将Hibernate查询中的符号映射到SQL查询中的符号 (符号可能是函数名或常量名字).
            <p><span class="strong">取值</span> <tt class="literal">hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.hbm2ddl.auto</tt></td>
            <td>在<tt class="literal">SessionFactory</tt>创建时，自动将数据库schema的DDL导出到数据库. 使用 <tt class="literal">create-drop</tt>时,在显式关闭<tt class="literal">SessionFactory</tt>时，将drop掉数据库schema.
            <p><span class="strong">取值</span> <tt class="literal">update</tt> | <tt class="literal">create</tt> | <tt class="literal">create-drop</tt> </p>
            </td>
        </tr>
        <tr>
            <td><tt class="literal">hibernate.cglib.use_reflection_optimizer</tt></td>
            <td>开启CGLIB来替代运行时反射机制(系统级属性). 反射机制有时在除错时比较有用. 注意即使关闭这个优化, Hibernate还是需要CGLIB. 你不能在<tt class="literal">hibernate.cfg.xml</tt>中设置此属性.
            <p><span class="strong">取值</span> <tt class="literal">true</tt> | <tt class="literal">false</tt> </p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-dialects"></a>3.4.1.&nbsp; SQL方言 </h3>
<p>你应当总是为你的数据库属性<tt class="literal">hibernate.dialect</tt>设置正确的 <tt class="literal">org.hibernate.dialect.Dialect</tt>子类. 如果你指定一种方言, Hibernate将为上面列出的一些属性使用合理的默认值, 为你省去了手工指定它们的功夫. </p>
<div class="table"><a name="sql-dialects"></a>
<p class="title"><strong>表&nbsp;3.8.&nbsp; Hibernate SQL方言 (<tt class="literal">hibernate.dialect</tt>) </strong></p>
<table summary="                    Hibernate SQL方言 (hibernate.dialect)&#10;                " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>RDBMS</th>
            <th>方言 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>DB2</td>
            <td><tt class="literal">org.hibernate.dialect.DB2Dialect</tt></td>
        </tr>
        <tr>
            <td>DB2 AS/400</td>
            <td><tt class="literal">org.hibernate.dialect.DB2400Dialect</tt></td>
        </tr>
        <tr>
            <td>DB2 OS390</td>
            <td><tt class="literal">org.hibernate.dialect.DB2390Dialect</tt></td>
        </tr>
        <tr>
            <td>PostgreSQL</td>
            <td><tt class="literal">org.hibernate.dialect.PostgreSQLDialect</tt></td>
        </tr>
        <tr>
            <td>MySQL</td>
            <td><tt class="literal">org.hibernate.dialect.MySQLDialect</tt></td>
        </tr>
        <tr>
            <td>MySQL with InnoDB</td>
            <td><tt class="literal">org.hibernate.dialect.MySQLInnoDBDialect</tt></td>
        </tr>
        <tr>
            <td>MySQL with MyISAM</td>
            <td><tt class="literal">org.hibernate.dialect.MySQLMyISAMDialect</tt></td>
        </tr>
        <tr>
            <td>Oracle (any version)</td>
            <td><tt class="literal">org.hibernate.dialect.OracleDialect</tt></td>
        </tr>
        <tr>
            <td>Oracle 9i/10g</td>
            <td><tt class="literal">org.hibernate.dialect.Oracle9Dialect</tt></td>
        </tr>
        <tr>
            <td>Sybase</td>
            <td><tt class="literal">org.hibernate.dialect.SybaseDialect</tt></td>
        </tr>
        <tr>
            <td>Sybase Anywhere</td>
            <td><tt class="literal">org.hibernate.dialect.SybaseAnywhereDialect</tt></td>
        </tr>
        <tr>
            <td>Microsoft SQL Server</td>
            <td><tt class="literal">org.hibernate.dialect.SQLServerDialect</tt></td>
        </tr>
        <tr>
            <td>SAP DB</td>
            <td><tt class="literal">org.hibernate.dialect.SAPDBDialect</tt></td>
        </tr>
        <tr>
            <td>Informix</td>
            <td><tt class="literal">org.hibernate.dialect.InformixDialect</tt></td>
        </tr>
        <tr>
            <td>HypersonicSQL</td>
            <td><tt class="literal">org.hibernate.dialect.HSQLDialect</tt></td>
        </tr>
        <tr>
            <td>Ingres</td>
            <td><tt class="literal">org.hibernate.dialect.IngresDialect</tt></td>
        </tr>
        <tr>
            <td>Progress</td>
            <td><tt class="literal">org.hibernate.dialect.ProgressDialect</tt></td>
        </tr>
        <tr>
            <td>Mckoi SQL</td>
            <td><tt class="literal">org.hibernate.dialect.MckoiDialect</tt></td>
        </tr>
        <tr>
            <td>Interbase</td>
            <td><tt class="literal">org.hibernate.dialect.InterbaseDialect</tt></td>
        </tr>
        <tr>
            <td>Pointbase</td>
            <td><tt class="literal">org.hibernate.dialect.PointbaseDialect</tt></td>
        </tr>
        <tr>
            <td>FrontBase</td>
            <td><tt class="literal">org.hibernate.dialect.FrontbaseDialect</tt></td>
        </tr>
        <tr>
            <td>Firebird</td>
            <td><tt class="literal">org.hibernate.dialect.FirebirdDialect</tt></td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-outerjoin"></a>3.4.2.&nbsp; 外连接抓取(Outer Join Fetching) </h3>
<p>如果你的数据库支持ANSI, Oracle或Sybase风格的外连接, <span class="emphasis"><em>外连接抓取</em></span>常能通过限制往返数据库次数 (更多的工作交由数据库自己来完成)来提高效率. 外连接允许在单个<tt class="literal">SELECT</tt>SQL语句中， 通过many-to-one, one-to-many, many-to-many和one-to-one关联获取连接对象的整个对象图. </p>
<p>将<tt class="literal">hibernate.max_fetch_depth</tt>设为<tt class="literal">0</tt>能在<span class="emphasis"><em>全局</em></span> 范围内禁止外连接抓取. 设为<tt class="literal">1</tt>或更高值能启用one-to-one和many-to-oneouter关联的外连接抓取, 它们通过 <tt class="literal">fetch="join"</tt>来映射. </p>
<p>参见<a title="19.1.&nbsp;&#10;&#9;&#10;&#9;&#9;&#9;抓取策略(Fetching strategies)" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/performance.html#performance-fetching">第&nbsp;19.1&nbsp;节 &#8220; 抓取策略(Fetching strategies) &#8221;</a>获得更多信息. </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-binarystreams"></a>3.4.3.&nbsp; 二进制流 (Binary Streams) </h3>
<p>Oracle限制那些通过JDBC驱动传输的<tt class="literal">字节</tt>数组的数目. 如果你希望使用<tt class="literal">二进值 (binary)</tt>或 <tt class="literal">可序列化的 (serializable)</tt>类型的大对象, 你应该开启 <tt class="literal">hibernate.jdbc.use_streams_for_binary</tt>属性. <span class="emphasis"><em>这是系统级属性.</em></span> </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-cacheprovider"></a>3.4.4.&nbsp; 二级缓存与查询缓存 </h3>
<p>以<tt class="literal">hibernate.cache</tt>为前缀的属性允许你在Hibernate中，使用进程或群集范围内的二级缓存系统. 参见<a title="19.2.&nbsp;二级缓存（The Second Level Cache）" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/performance.html#performance-cache">第&nbsp;19.2&nbsp;节 &#8220;二级缓存（The Second Level Cache） &#8221;</a>获取更多的详情. </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-querysubstitution"></a>3.4.5.&nbsp; 查询语言中的替换 </h3>
<p>你可以使用<tt class="literal">hibernate.query.substitutions</tt>在Hibernate中定义新的查询符号. 例如: </p>
<pre class="programlisting">hibernate.query.substitutions true=1, false=0</pre>
<p>将导致符号<tt class="literal">true</tt>和<tt class="literal">false</tt>在生成的SQL中被翻译成整数常量. </p>
<pre class="programlisting">hibernate.query.substitutions toLowercase=LOWER</pre>
<p>将允许你重命名SQL中的<tt class="literal">LOWER</tt>函数. </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-statistics"></a>3.4.6.&nbsp; Hibernate的统计(statistics)机制 </h3>
<p>如果你开启<tt class="literal">hibernate.generate_statistics</tt>, 那么当你通过 <tt class="literal">SessionFactory.getStatistics()</tt>调整正在运行的系统时，Hibernate将导出大量有用的数据. Hibernate甚至能被配置成通过JMX导出这些统计信息. 参考<tt class="literal">org.hibernate.stats</tt>中接口的Javadoc，以获得更多信息. </p>
</div>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="configuration-logging"></a>3.5.&nbsp; 日志 </h2>
<p>Hibernate使用Apache commons-logging来为各种事件记录日志. </p>
<p>commons-logging将直接输出到Apache Log4j(如果在类路径中包括<tt class="literal">log4j.jar</tt>)或 JDK1.4 logging (如果运行在JDK1.4或以上的环境下). 你可以从<tt class="literal">http://jakarta.apache.org</tt> 下载Log4j. 要使用Log4j，你需要将<tt class="literal">log4j.properties</tt>文件放置在类路径下, 随Hibernate 一同分发的样例属性文件在<tt class="literal">src/</tt>目录下. </p>
<p>我们强烈建议你熟悉一下Hibernate的日志消息. 在不失可读性的前提下， 我们做了很多工作，使Hibernate的日志可能地详细. 这是必要的查错利器. 最令人感兴趣的日志分类有如下这些: </p>
<div class="table"><a name="log-categories"></a>
<p class="title"><strong>表&nbsp;3.9.&nbsp; Hibernate日志类别 </strong></p>
<table summary="                    Hibernate日志类别&#10;                " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>类别 </th>
            <th>功能 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">org.hibernate.SQL</tt></td>
            <td>在所有SQL DML语句被执行时为它们记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.type</tt></td>
            <td>为所有JDBC参数记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.tool.hbm2ddl</tt></td>
            <td>在所有SQL DDL语句执行时为它们记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.pretty</tt></td>
            <td>在session清洗(flush)时，为所有与其关联的实体(最多20个)的状态记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.cache</tt></td>
            <td>为所有二级缓存的活动记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction</tt></td>
            <td>为事务相关的活动记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.jdbc</tt></td>
            <td>为所有JDBC资源的获取记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.hql.ast</tt></td>
            <td>为HQL和SQL的自动状态转换和其他关于查询解析的信息记录日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.secure</tt></td>
            <td>为JAAS认证请求做日志 </td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate</tt></td>
            <td>为任何Hibernate相关信息做日志 (信息量较大, 但对查错非常有帮助) </td>
        </tr>
    </tbody>
</table>
</div>
<p>在使用Hibernate开发应用程序时, 你应当总是为<tt class="literal">org.hibernate.SQL</tt> 开启<tt class="literal">debug</tt>级别的日志记录,或者开启<tt class="literal">hibernate.show_sql</tt>属性来代替它。. </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="configuration-namingstrategy"></a>3.6.&nbsp; 实现<tt class="literal">NamingStrategy</tt> </h2>
<p><tt class="literal">org.hibernate.cfg.NamingStrategy</tt>接口允许你为数据库中的对象和schema 元素指定一个&#8220;命名标准&#8221;. </p>
<p>你可能会提供一些通过Java标识生成数据库标识或将映射定义文件中"逻辑"表/列名处理成"物理"表/列名的规则. 这个特性有助于减少冗长的映射定义文件. </p>
<p>在加入映射定义前，你可以调用 <tt class="literal">Configuration.setNamingStrategy()</tt>指定一个不同的命名策略: </p>
<pre class="programlisting">SessionFactory sf = new Configuration()
.setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
.addFile("Item.hbm.xml")
.addFile("Bid.hbm.xml")
.buildSessionFactory();</pre>
<p><tt class="literal">org.hibernate.cfg.ImprovedNamingStrategy</tt>是一个内建的命名策略, 对 一些应用程序而言，可能是非常有用的起点. </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="configuration-xmlconfig"></a>3.7.&nbsp; XML配置文件 </h2>
<p>另一个配置方法是在<tt class="literal">hibernate.cfg.xml</tt>文件中指定一套完整的配置. 这个文件可以当成<tt class="literal">hibernate.properties</tt>的替代。 若两个文件同时存在，它将重载前者的属性. </p>
<p>XML配置文件被默认是放在<tt class="literal">CLASSPATH</tt>的根目录下. 这是一个例子: </p>
<p>&nbsp;</p>
<pre class="programlisting">&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&gt;
&lt;hibernate-configuration&gt;
&lt;!-- 以/jndi/name绑定到JNDI的SessionFactory实例 --&gt;
&lt;session-factory
name="java:hibernate/SessionFactory"&gt;
&lt;!-- 属性 --&gt;
&lt;property name="connection.datasource"&gt;java:/comp/env/jdbc/MyDB&lt;/property&gt;
&lt;property name="dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;
&lt;property name="show_sql"&gt;false&lt;/property&gt;
&lt;property name="transaction.factory_class"&gt;
org.hibernate.transaction.JTATransactionFactory
&lt;/property&gt;
&lt;property name="jta.UserTransaction"&gt;java:comp/UserTransaction&lt;/property&gt;
&lt;!-- 映射定义文件 --&gt;
&lt;mapping resource="org/hibernate/auction/Item.hbm.xml"/&gt;
&lt;mapping resource="org/hibernate/auction/Bid.hbm.xml"/&gt;
&lt;!-- 缓存设置 --&gt;
&lt;class-cache class="org.hibernate.auction.Item" usage="read-write"/&gt;
&lt;class-cache class="org.hibernate.auction.Bid" usage="read-only"/&gt;
&lt;collection-cache class="org.hibernate.auction.Item.bids" usage="read-write"/&gt;
&lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;</pre>
<p>如你所见, 这个方法优势在于，在配置文件中指出了映射定义文件的名字. 一旦你需要调整Hibernate的缓存， <tt class="literal">hibernate.cfg.xml</tt>也是更方便. 注意，使用<tt class="literal">hibernate.properties</tt>还是 <tt class="literal">hibernate.cfg.xml</tt>完全是由你来决定, 除了上面提到的XML语法的优势之外, 两者是等价的. </p>
<p>使用XML配置，使得启动Hibernate变的异常简单, 如下所示，一行代码就可以搞定： </p>
<pre class="programlisting">SessionFactory sf = new Configuration().configure().buildSessionFactory();</pre>
<p>你可以使用如下代码来添加一个不同的XML配置文件 </p>
<pre class="programlisting">SessionFactory sf = new Configuration()
.configure("catdb.cfg.xml")
.buildSessionFactory();</pre>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="configuration-j2ee"></a>3.8.&nbsp; J2EE应用程序服务器的集成 </h2>
<p>针对J2EE体系,Hibernate有如下几个集成的方面: </p>
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p><span class="emphasis"><em>容器管理的数据源(Container-managed datasources)</em></span>: Hibernate能通过容器管理由JNDI提供的JDBC连接. 通常, 特别是当处理多个数据源的分布式事务的时候, 由一个JTA兼容的<tt class="literal">TransactionManager</tt>和一个 <tt class="literal">ResourceManager</tt>来处理事务管理(CMT, 容器管理的事务). 当然你可以通过 编程方式来划分事务边界(BMT, Bean管理的事务). 或者为了代码的可移植性，你也也许会想使用可选的 Hibernate <tt class="literal">Transaction</tt> API. </p>
    </li>
</ul>
</div>
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p><span class="emphasis"><em>自动JNDI绑定</em></span>: Hibernate可以在启动后将 <tt class="literal">SessionFactory</tt>绑定到JNDI. </p>
    </li>
</ul>
</div>
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p><span class="emphasis"><em>JTA Session绑定:</em></span> 如果使用EJB, Hibernate <tt class="literal">Session</tt> 可以自动绑定到JTA事务作用的范围. 只需简单地从JNDI查找<tt class="literal">SessionFactory</tt>并获得当前的 <tt class="literal">Session</tt>. 当JTA事务完成时, 让Hibernate来处理 <tt class="literal">Session</tt>的清洗(flush)与关闭. 在EJB的部署描述符中事务边界是声明式的. </p>
    </li>
</ul>
</div>
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p><span class="emphasis"><em>JMX部署:</em></span> 如果你使用支持JMX应用程序服务器(如, JBoss AS), 那么你可以选择将Hibernate部署成托管MBean. 这将为你省去一行从<tt class="literal">Configuration</tt>构建<tt class="literal">SessionFactory</tt>的启动代码. 容器将启动你的<tt class="literal">HibernateService</tt>, 并完美地处理好服务间的依赖关系 (在Hibernate启动前，数据源必须是可用的等等). </p>
    </li>
</ul>
</div>
<p>如果应用程序服务器抛出"connection containment"异常, 根据你的环境，也许该将配置属性 <tt class="literal">hibernate.connection.release_mode</tt>设为<tt class="literal">after_statement</tt>. </p>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-transactionstrategy"></a>3.8.1.&nbsp; 事务策略配置 </h3>
<p>在你的架构中，Hibernate的<tt class="literal">Session</tt> API是独立于任何事务分界系统的. 如果你让Hibernate通过连接池直接使用JDBC, 你需要调用JDBC API来打开和关闭你的事务. 如果你运行在J2EE应用程序服务器中, 你也许想用Bean管理的事务并在需要的时候调用JTA API和<tt class="literal">UserTransaction</tt>. </p>
<p>为了让你的代码在两种(或其他)环境中可以移植，我们建议使用可选的Hibernate <tt class="literal">Transaction</tt> API, 它包装并隐藏了底层系统. 你必须通过设置Hibernate配置属性<tt class="literal">hibernate.transaction.factory_class</tt>来指定 一个<tt class="literal">Transaction</tt>实例的工厂类. </p>
<p>存在着三个标准(内建)的选择: </p>
<div class="variablelist">
<dl>
<dt><span class="term"><tt class="literal">org.hibernate.transaction.JDBCTransactionFactory</tt></span></dt>
<dd>
<p>委托给数据库(JDBC)事务（默认） </p>
</dd>
<dt><span class="term"><tt class="literal">org.hibernate.transaction.JTATransactionFactory</tt></span></dt>
<dd>
<p>如果在上下文环境中存在运行着的事务(如, EJB会话Bean的方法), 则委托给容器管 理的事务, 否则，将启动一个新的事务，并使用Bean管理的事务. </p>
</dd>
<dt><span class="term"><tt class="literal">org.hibernate.transaction.CMTTransactionFactory</tt></span></dt>
<dd>
<p>委托给容器管理的JTA事务 </p>
</dd></dl></div>
<p>你也可以定义属于你自己的事务策略 (如, 针对CORBA的事务服务) </p>
<p>Hibernate的一些特性 (即二级缓存, JTA与Session的自动绑定等等)需要访问在托管环境中的JTA <tt class="literal">TransactionManager</tt>. 由于J2EE没有标准化一个单一的机制,Hibernate在应用程序服务器中，你必须指定Hibernate如何获得<tt class="literal">TransactionManager</tt>的引用: </p>
<div class="table"><a name="jtamanagerlookup"></a>
<p class="title"><strong>表&nbsp;3.10.&nbsp;JTA TransactionManagers</strong></p>
<table summary="JTA TransactionManagers" border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th>Transaction工厂类 </th>
            <th align="center">应用程序服务器 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.JBossTransactionManagerLookup</tt></td>
            <td align="center">JBoss</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.WeblogicTransactionManagerLookup</tt></td>
            <td align="center">Weblogic</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.WebSphereTransactionManagerLookup</tt></td>
            <td align="center">WebSphere</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</tt></td>
            <td align="center">WebSphere 6</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.OrionTransactionManagerLookup</tt></td>
            <td align="center">Orion</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.ResinTransactionManagerLookup</tt></td>
            <td align="center">Resin</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.JOTMTransactionManagerLookup</tt></td>
            <td align="center">JOTM</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.JOnASTransactionManagerLookup</tt></td>
            <td align="center">JOnAS</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.JRun4TransactionManagerLookup</tt></td>
            <td align="center">JRun4</td>
        </tr>
        <tr>
            <td><tt class="literal">org.hibernate.transaction.BESTransactionManagerLookup</tt></td>
            <td align="center">Borland ES</td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-optional-jndi"></a>3.8.2.&nbsp; JNDI绑定的<tt class="literal">SessionFactory</tt> </h3>
<p>与JNDI绑定的Hibernate的<tt class="literal">SessionFactory</tt>能简化工厂的查询，简化创建新的<tt class="literal">Session</tt>. 需要注意的是这与JNDI绑定<tt class="literal">Datasource</tt>没有关系, 它们只是恰巧用了相同的注册表! </p>
<p>如果你希望将<tt class="literal">SessionFactory</tt>绑定到一个JNDI的名字空间, 用属性<tt class="literal">hibernate.session_factory_name</tt>指定一个名字(如, <tt class="literal">java:hibernate/SessionFactory</tt>). 如果不设置这个属性, <tt class="literal">SessionFactory</tt>将不会被绑定到JNDI中. (在以只读JNDI为默认实现的环境中，这个设置尤其有用, 如Tomcat.) </p>
<p>在将<tt class="literal">SessionFactory</tt>绑定至JNDI时, Hibernate将使用<tt class="literal">hibernate.jndi.url</tt>, 和<tt class="literal">hibernate.jndi.class</tt>的值来实例化初始环境(initial context). 如果它们没有被指定, 将使用默认的<tt class="literal">InitialContext</tt>. </p>
<p>在你调用<tt class="literal">cfg.buildSessionFactory()</tt>后, Hibernate会自动将<tt class="literal">SessionFactory</tt>注册到JNDI. 这意味这你至少需要在你应用程序的启动代码(或工具类)中完成这个调用, 除非你使用<tt class="literal">HibernateService</tt>来做JMX部署 (见后面讨论). </p>
<p>如果你使用与JNDI绑定的<tt class="literal">SessionFactory</tt>, EJB或任何其他类可以通过一个JNDI查询来获得这个<tt class="literal">SessionFactory</tt>. 请注意, 如果你使用第一章中介绍的帮助类<tt class="literal">HibernateUtil</tt> - 类似Singleton(单实例)注册表, 那么这里的启动代码不是必要的. 但<tt class="literal">HibernateUtil</tt>更多被使用在非托管环境中. </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-j2ee-currentsession"></a>3.8.3.&nbsp; JTA和Session的自动绑定 </h3>
<p>在非托管环境中，我们建议：<tt class="literal">HibernateUtil</tt>和静态<tt class="literal">SessionFactory</tt>一起工作， 由<tt class="literal">ThreadLocal</tt>管理Hibernate <tt class="literal">Session</tt>。 由于一些EJB可能会运行在同一个事务但不同线程的环境中, 所以这个方法不能照搬到EJB环境中. 我们建议在托管环境中，将<tt class="literal">SessionFactory</tt>绑定到JNDI上. </p>
<p>请使用<tt class="literal">SessionFactory</tt>的<tt class="literal">getCurrentSession()</tt>方法来代替 直接使用<tt class="literal">ThreadLocal</tt>去获得Hibernate <tt class="literal">Session</tt>. 如果在当前JTA事务中没有Hibernate <tt class="literal">Session</tt>, 将会启动一个并将它关联到事务中. 对于使用<tt class="literal">getCurrentSession()</tt>获得的每个<tt class="literal">Session</tt>而言， <tt class="literal">hibernate.transaction.flush_before_completion</tt> 和<tt class="literal">hibernate.transaction.auto_close_session</tt>这两个配置选项会自动设置, 因此在容器结束JTA事务时，这些<tt class="literal">Session</tt>会被自动清洗(flush)并关闭. </p>
<p>例如，如果你使用DAO模式来编写你的持久层, 那么在需要时，所有DAO将查找<tt class="literal">SessionFactory</tt>并打开"当前"Session. 没有必要在控制代码和DAO代码间传递<tt class="literal">SessionFactory</tt>或<tt class="literal">Session</tt>的实例. </p>
</div>
<div class="sect2" lang="zh-cn">
<h3 class="title"><a name="configuration-j2ee-jmx"></a>3.8.4.&nbsp; JMX部署 </h3>
<p>为了将<tt class="literal">SessionFactory</tt>注册到JNDI中<tt class="literal">cfg.buildSessionFactory()</tt>这行代码仍需在某处被执行. 你可在一个<tt class="literal">static</tt>初始化块(像<tt class="literal">HibernateUtil</tt>中的那样)中执行它或将Hibernate部署为一个<span class="emphasis"><em>托管的服务</em></span>. </p>
<p>为了部署在一个支持JMX的应用程序服务器上，Hibernate和 <tt class="literal">org.hibernate.jmx.HibernateService</tt>一同分发，如Jboss AS。 实际的部署和配置是由应用程序服务器提供者指定的. 这里是JBoss 4.0.x的<tt class="literal">jboss-service.xml</tt>样例: </p>
<pre class="programlisting">&lt;?xml version="1.0"?&gt;
&lt;server&gt;
&lt;mbean code="org.hibernate.jmx.HibernateService"
name="jboss.jca:service=HibernateFactory,name=HibernateFactory"&gt;
&lt;!-- 必须的服务 --&gt;
&lt;depends&gt;jboss.jca:service=RARDeployer&lt;/depends&gt;
&lt;depends&gt;jboss.jca:service=LocalTxCM,name=HsqlDS&lt;/depends&gt;
&lt;!-- 将Hibernate服务绑定到JNDI --&gt;
&lt;attribute name="JndiName"&gt;java:/hibernate/SessionFactory&lt;/attribute&gt;
&lt;!-- 数据源设置 --&gt;
&lt;attribute name="Datasource"&gt;java:HsqlDS&lt;/attribute&gt;
&lt;attribute name="Dialect"&gt;org.hibernate.dialect.HSQLDialect&lt;/attribute&gt;
&lt;!-- 事务集成 --&gt;
&lt;attribute name="TransactionStrategy"&gt;
org.hibernate.transaction.JTATransactionFactory&lt;/attribute&gt;
&lt;attribute name="TransactionManagerLookupStrategy"&gt;
org.hibernate.transaction.JBossTransactionManagerLookup&lt;/attribute&gt;
&lt;attribute name="FlushBeforeCompletionEnabled"&gt;true&lt;/attribute&gt;
&lt;attribute name="AutoCloseSessionEnabled"&gt;true&lt;/attribute&gt;
&lt;!-- 抓取选项 --&gt;
&lt;attribute name="MaximumFetchDepth"&gt;5&lt;/attribute&gt;
&lt;!-- 二级缓存 --&gt;
&lt;attribute name="SecondLevelCacheEnabled"&gt;true&lt;/attribute&gt;
&lt;attribute name="CacheProviderClass"&gt;org.hibernate.cache.EhCacheProvider&lt;/attribute&gt;
&lt;attribute name="QueryCacheEnabled"&gt;true&lt;/attribute&gt;
&lt;!-- 日志 --&gt;
&lt;attribute name="ShowSqlEnabled"&gt;true&lt;/attribute&gt;
&lt;!-- 映射定义文件 --&gt;
&lt;attribute name="MapResources"&gt;auction/Item.hbm.xml,auction/Category.hbm.xml&lt;/attribute&gt;
&lt;/mbean&gt;
&lt;/server&gt;</pre>
<p>这个文件是部署在<tt class="literal">META-INF</tt>目录下的, 并会被打包到以<tt class="literal">.sar</tt> (service archive)为扩展名的JAR文件中. 同时，你需要打包Hibernate, 它所需要的第三方库, 你编译好的持久化类及你的映射定义文件打包进同一个文档. 你的企业Bean(一般为会话Bean)可能会被打包成它们自己的JAR文件, 但你也许会将EJB JAR文件一同包含进能独立(热)部署的主服务文档. 咨询JBoss AS文档以了解更多的JMX服务与EJB部署的信息. </p>
</div>
</div><img src ="http://www.blogjava.net/mikecheers/aggbug/182908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikecheers/" target="_blank">Mike Cheers</a> 2008-02-29 14:07 <a href="http://www.blogjava.net/mikecheers/articles/182908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第 2 章 架构(Architecture)</title><link>http://www.blogjava.net/mikecheers/articles/182905.html</link><dc:creator>Mike Cheers</dc:creator><author>Mike Cheers</author><pubDate>Fri, 29 Feb 2008 05:56:00 GMT</pubDate><guid>http://www.blogjava.net/mikecheers/articles/182905.html</guid><wfw:comment>http://www.blogjava.net/mikecheers/comments/182905.html</wfw:comment><comments>http://www.blogjava.net/mikecheers/articles/182905.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikecheers/comments/commentRss/182905.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikecheers/services/trackbacks/182905.html</trackback:ping><description><![CDATA[<div class="titlepage">
<h2 class="title">第&nbsp;2&nbsp;章&nbsp;架构(Architecture)</h2>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="architecture-overview"></a>2.1.&nbsp;概况(Overview)</h2>
<p>一个非常简要的Hibernate架构的概要图： </p>
<div class="mediaobject" align="center"><img src="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/shared/images/overview.gif" align="center"  alt="" /></div>
<p>从这个图可以看出，Hibernater使用数据库和配置信息来为应用程序提供持久化服务（以及持久的对象）。 </p>
<p>我们来更详细地看一下Hibernate运行时架构。由于Hibernate非常灵活，且支持数种应用方案， 所以我们这只描述一下两种极端的情况。&#8220;轻型&#8221;的架构方案，要求应用程序提供自己的JDBC 连接并管理自己的事务。这种方案使用了Hibernate API的最小子集： </p>
<div class="mediaobject" align="center"><img src="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/shared/images/lite.gif" align="center"  alt="" /></div>
<p>&#8220;全面解决&#8221;的架构方案，将应用层从底层的JDBC/JTA API中抽象出来，而让Hibernate来处理这些细节。 </p>
<div class="mediaobject" align="center"><img src="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/shared/images/full_cream.gif" align="center"  alt="" /></div>
<p>Heres some definitions of the objects in the diagrams: 图中各个对象的定义如下： </p>
<div class="variablelist">
<dl>
<dt><span class="term">SessionFactory (<tt class="literal">org.hibernate.SessionFactory</tt>)</span></dt>
<dd>
<p>针对单个数据库映射关系经过编译后的内存镜像，它也是线程安全的（不可变）。 它是生成<tt class="literal">Session</tt>的工厂，本身要用到<tt class="literal">ConnectionProvider</tt>。 该对象可以在进程或集群的级别上，为那些事务之间可以重用的数据提供可选的二级缓存。 </p>
</dd>
<dt><span class="term">Session (<tt class="literal">org.hibernate.Session</tt>)</span></dt>
<dd>
<p>表示应用程序与持久储存层之间交互操作的一个单线程对象，此对象生存期很短。 其隐藏了JDBC连接，也是<tt class="literal">Transaction</tt>的工厂。 其会持有一个针对持久化对象的必选（第一级）缓存，在遍历对象图或者根据持久化标识查找对象时会用到。 </p>
</dd>
<dt><span class="term">持久的对象及其集合</span></dt>
<dd>
<p>带有持久化状态的、具有业务功能的单线程对象，此对象生存期很短。 这些对象可以是普通的JavaBeans/POJO，唯一特殊的是他们正与（仅仅一个）<tt class="literal">Session</tt>相关联。 这个<tt class="literal">Session</tt>被关闭的同时，这些对象也会脱离持久化状态，可以被应用程序的任何层自由使用。 （例如，用作跟表示层打交道的数据传输对象data transfer object。） </p>
</dd>
<dt><span class="term">瞬态(transient)以及脱管(detached)的对象及其集合</span></dt>
<dd>
<p>持久类的没有与<tt class="literal">Session</tt>相关联的实例。 他们可能是在被应用程序实例化后，尚未进行持久化的对象。 也可能是因为实例化他们的<tt class="literal">Session</tt>已经被关闭而脱离持久化的对象。 </p>
</dd>
<dt><span class="term">事务Transaction (<tt class="literal">org.hibernate.Transaction</tt>)</span></dt>
<dd>
<p>（可选的）应用程序用来指定原子操作单元范围的对象，它是单线程的，生存期很短。 它通过抽象将应用从底层具体的JDBC、JTA以及CORBA事务隔离开。 某些情况下，一个<tt class="literal">Session</tt>之内可能包含多个<tt class="literal">Transaction</tt>对象。 尽管是否使用该对象是可选的，但是事务边界的开启与关闭（无论是使用底层的API还是使用<tt class="literal">Transaction</tt>对象）是必不可少的。 </p>
</dd>
<dt><span class="term">ConnectionProvider (<tt class="literal">org.hibernate.connection.ConnectionProvider</tt>)</span></dt>
<dd>
<p>（可选的）生成JDBC连接的工厂（同时也起到连接池的作用）。 它通过抽象将应用从底层的<tt class="literal">Datasource</tt>或<tt class="literal">DriverManager</tt>隔离开。 仅供开发者扩展/实现用，并不暴露给应用程序使用。 </p>
</dd>
<dt><span class="term">TransactionFactory (<tt class="literal">org.hibernate.TransactionFactory</tt>)</span></dt>
<dd>
<p>（可选的）生成<tt class="literal">Transaction</tt>对象实例的工厂。 仅供开发者扩展/实现用，并不暴露给应用程序使用。 </p>
</dd>
<dt><span class="term"><span class="emphasis"><em>扩展接口</em></span></span></dt>
<dd>
<p>Hibernate提供了很多可选的扩展接口，你可以通过实现它们来定制你的持久层的行为。 具体请参考API文档。 </p>
</dd></dl></div>
<p>&nbsp;</p>
<p>在一个&#8220;轻型&#8221;的架构中，应用程序可能绕过 <tt class="literal">Transaction</tt>/<tt class="literal">TransactionFactory</tt> 以及 <tt class="literal">ConnectionProvider</tt> 等API直接跟JTA或JDBC打交道。 </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">2.2.&nbsp;实例状态</h2>
<p>一个持久化类的实例可能处于三种不同状态中的某一种。 这三种状态的定义则与所谓的<span class="emphasis"><em>持久化上下文(persistence context)</em></span>有关。 Hibernate的<tt class="literal">Session</tt>对象就是这个所谓的持久化上下文： </p>
<div class="variablelist">
<dl>
<dt><span class="term">瞬态（transient）</span></dt>
<dd>
<p>该实例从未与任何持久化上下文关联过。它没有持久化标识（相当于主键）。 </p>
</dd>
<dt><span class="term">持久(persistent)</span></dt>
<dd>
<p>实例目前与某个持久化上下文有关联。 它拥有持久化标识（相当于主键），并且可能在数据库中有一个对应的行。 对于某一个特定的持久化上下文，Hibernate<span class="emphasis"><em>保证</em></span>持久化标识与Java标识（其值代表对象在内存中的位置）等价。 </p>
</dd>
<dt><span class="term">脱管(detached)</span></dt>
<dd>
<p>实例曾经与某个持久化上下文发生过关联，不过那个上下文被关闭了， 或者这个实例是被序列化(serialize)到这个进程来的。 它拥有持久化标识，并且在数据库中可能存在一个对应的行。 对于脱管状态的实例，Hibernate不保证任何持久化标识和Java标识的关系。 </p>
</dd></dl></div>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">2.3.&nbsp;JMX整合</h2>
<p>JMX是管理Java组件(Java components)的J2EE规范。 Hibernate 可以通过一个JMX标准服务来管理。 在这个发行版本中，我们提供了一个MBean接口的实现,即 <tt class="literal">org.hibernate.jmx.HibernateService</tt>。 </p>
<p>想要看如何在JBoss应用服务器上将Hibernate部署为一个JMX服务的例子，您可以参考JBoss用户指南。 我们现在说一下在Jboss应用服务器上，使用JMX来部署Hibernate的好处： </p>
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p><span class="emphasis"><em>Session管理：</em></span> Hibernate的<tt class="literal">Session</tt>对象的生命周期可以 自动跟一个JTA事务边界绑定。这意味着你无需手工开关<tt class="literal">Session</tt>了, 这项 工作会由JBoss EJB 拦截器来完成。你再也不用担心你的代码中的事务边界了(除非你想利用Hibernate提供 的<tt class="literal">Transaction</tt> API来自己写一个便于移植的的持久层)。 你现在要通过 <tt class="literal">HibernateContext</tt>来操作<tt class="literal">Session</tt>了。 </p>
    </li>
    <li>
    <p><span class="emphasis"><em>HAR 部署:</em></span> 通常情况下，你会使用JBoss的服务部署描述符（在EAR或/和SAR文件中）来部署Hibernate JMX服务。 这种部署方式支持所有常见的Hibernate <tt class="literal">SessionFactory</tt>的配置选项。 不过，你需在部署描述符中，列出你所有的映射文件的名字。如果你使用HAR部署方式, JBoss 会自动探测出你的HAR文件中所有的映射文件。 </p>
    </li>
</ul>
</div>
<p>这些选项更多的描述，请参考JBoss 应用程序用户指南。 </p>
<p>将Hibernate以部署为JMX服务的另一个好处，是可以查看Hibernate的运行时统计信息。参看 <a title="3.4.6.&nbsp;&#10;                Hibernate的统计(statistics)机制&#10;            " href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/session-configuration.html#configuration-optional-statistics">第&nbsp;3.4.6&nbsp;节 &#8220; Hibernate的统计(statistics)机制 &#8221;</a>. </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">2.4.&nbsp;对JCA的支持</h2>
<p>Hibernate也可以被配置为一个JCA连接器（JCA connector）。更多信息请参看网站。 请注意，Hibernate对JCA的支持，仍处于实验性质。 </p>
</div><img src ="http://www.blogjava.net/mikecheers/aggbug/182905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikecheers/" target="_blank">Mike Cheers</a> 2008-02-29 13:56 <a href="http://www.blogjava.net/mikecheers/articles/182905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第 1 章 在Tomcat中快速上手</title><link>http://www.blogjava.net/mikecheers/articles/182904.html</link><dc:creator>Mike Cheers</dc:creator><author>Mike Cheers</author><pubDate>Fri, 29 Feb 2008 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/mikecheers/articles/182904.html</guid><wfw:comment>http://www.blogjava.net/mikecheers/comments/182904.html</wfw:comment><comments>http://www.blogjava.net/mikecheers/articles/182904.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikecheers/comments/commentRss/182904.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikecheers/services/trackbacks/182904.html</trackback:ping><description><![CDATA[<h2 class="title">第&nbsp;1&nbsp;章&nbsp;在Tomcat中快速上手</h2>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">1.1.&nbsp;开始Hibernate之旅</h2>
<p>这份教程描述如何在Apache Tomcat servlet容器中为web应用程序配置Hibernate 3.0(我们使用Tomcat 4.1版本，与5.0版本差别很小)。Hibernate在大多数主流J2EE应用服务器 的运行环境中都可以工作良好，甚至也可以在独立Java应用程序中使用。在本教程中使用的示例数据库系统是PostgreSQL 7.4,只需要修改Hibernate SQL语言配置与连接属性，就可以 很容易的支持其他数据库了。 </p>
<p>第一步，我们必须拷贝所有需要的库文件到Tomcat安装目录中。在这篇教程中，我们使用一个独立的web Context配置（<tt class="literal">webapps/quickstart</tt>）。我们确认全局库文件（<tt class="literal">TOMCAT/common/lib</tt>）和本web应用程序上下文的路径（对于jar来说是<tt class="literal">webapps/quickstart/WEB-INF/lib</tt>，对于class文件来说是<tt class="literal">webapps/quickstart/WEB-INF/classes</tt>）能够被类装载器classloder检索到。我们把这两个类装载器级别分别称做全局类路径(global classpath)和上下文类路径(context classpath)。 </p>
<p>现在，把这些库文件copy到两个类路径去: </p>
<div class="orderedlist">
<ol type="1">
    <li>
    <p>把数据库需要的JDBC驱动文件拷贝到全局类路径，这是tomcat捆绑的DBCP连接池所需要的。Hibernate使用JDBC连接数据库方式执行 SQL语句，所以你要么提供外部连接池中的连接给Hibernate，或者配置Hibernate自带的连接池（C3PO,Proxool）。对于本教程来说，把<tt class="literal">pg74jdbc3.jar</tt>库文件（支持PostgreSQL 7.4和JDK 1.4)到全局类装载路径下即可。如果你希望使用其他的数据库，拷贝其相应的JDBC 驱动文件）。 </p>
    <li>
    <p>永远不要拷贝任何其他东西到Tomcat的全局类路径下，否则你可能在使用其他一些工具上遇到麻烦，比如log4j, commons-logging等等。 一定要让每个web应用程序使用自己的上下文类路径，就是说把你自己需要的类库拷贝到<tt class="literal">WEB-INF/lib</tt>下去，把配置文件configuration/property等配置文件拷贝到<tt class="literal">WEB-INF/classes</tt>下面去。这两个目录都是当前程序缺省的上下文类路径。 </p>
    <li>
    <p>Hibernate本身打包成一个JAR类库。将<tt class="literal">hibernate3.jar</tt>文件拷贝到程序的上下文类路径下，和你应用程序的其他库文件放一起。在运行时，Hibernate还需要一些第三方类库，它们在Hibernate发行包的<tt class="literal">lib/</tt>目录下。参见<a title="表&nbsp;1.1.&nbsp;&#10;                Hibernate 第三方类库&#10;            " href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/quickstart.html#3rdpartylibs">表&nbsp;1.1 &#8220; Hibernate 第三方类库 &#8221;</a>。把所需要的第三方库文件也拷贝到上下文类路径下。 </p>
    </li>
</ol>
</div>
<div class="table"><a name="3rdpartylibs"></a>
<p class="title"><strong>表&nbsp;1.1.&nbsp; Hibernate 第三方类库 </strong></p>
<table summary="                Hibernate 第三方类库&#10;            " border="1">
    <colgroup>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th align="center">类库 </th>
            <th align="center">描述 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>antlr (必需) </td>
            <td>Hibernate使用ANTLR来产生查询分析器，这个类库在运行环境下时也是必需的。 </td>
        </tr>
        <tr>
            <td>dom4j (必需) </td>
            <td>Hibernate使用dom4j解析XML配置文件和XML映射元文件。 </td>
        </tr>
        <tr>
            <td>CGLIB ,asm(必需) </td>
            <td>Hibernate在运行时使用这个代码生成库增强类（与Java反射机制联合使用）。 </td>
        </tr>
        <tr>
            <td>Commons Collections, Commons Logging (必需) </td>
            <td>Hibernat使用Apache Jakarta Commons项目提供的多个工具类库。 </td>
        </tr>
        <tr>
            <td>EHCache (必需) </td>
            <td>Hibernate可以使用不同cache缓存工具作为二级缓存。EHCache是缺省的cache缓存工具。 </td>
        </tr>
        <tr>
            <td>Log4j (可选) </td>
            <td>Hibernate使用Commons Logging API,它也可以依次使用Log4j作为底层实施log的机制。如果上下文类目录中存在Log4j库，则Commons Logging使用Log4j和并它在上下文类路径中寻找的<tt class="literal">log4j.properties</tt>文件。你可以使用在Hibernate发行包中包含中的那个示例Log4j的配置文件。这样，把log4j.jar和它的配置文件（位于<tt class="literal">src/</tt>目录中）拷贝到你的上下文类路径下，就可以在后台看到底程序如何运行的。 </td>
        </tr>
        <tr>
            <td>其他文件是不是必需的？ </td>
            <td>请察看Hibernate发行包中的 lib/README.txt文件，这是一个Hibernate发行包中附带的第三方类库的列表，他们总是保持最新的。你可以在那里找到所有必需或者可选的类库(注意：其中的"buildtime required"指的是编译Hibernate时所需要而非编译你自己的程序所必需的类库）。 </td>
        </tr>
    </tbody>
</table>
</div>
<p>接下来我们来配置在Tomcat和Hibernate中共用的数据库连接池。也就是说Tomcat会提供经过池处理的JDBC连接（用它内置的DBCP连接池），Hibernate通过JNDI方式来请求获得JDBC连接。作为替代方案，你也可以让Hibernate自行管理连接池。Tomcat把连接池绑定到JNDI,我们要在Tomcat的主配置文件（<tt class="literal">TOMCAT/conf/server.xml</tt>）中加一个资源声明: </p>
<pre class="programlisting">&lt;Context path="/quickstart" docBase="quickstart"&gt;
&lt;Resource name="jdbc/quickstart" scope="Shareable" type="javax.sql.DataSource"/&gt;
&lt;ResourceParams name="jdbc/quickstart"&gt;
&lt;parameter&gt;
&lt;name&gt;factory&lt;/name&gt;
&lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;
&lt;/parameter&gt;
&lt;!-- DBCP database connection settings --&gt;
&lt;parameter&gt;
&lt;name&gt;url&lt;/name&gt;
&lt;value&gt;jdbc:postgresql://localhost/quickstart&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;driverClassName&lt;/name&gt;&lt;value&gt;org.postgresql.Driver&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;username&lt;/name&gt;
&lt;value&gt;quickstart&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;password&lt;/name&gt;
&lt;value&gt;secret&lt;/value&gt;
&lt;/parameter&gt;
&lt;!-- DBCP connection pooling options --&gt;
&lt;parameter&gt;
&lt;name&gt;maxWait&lt;/name&gt;
&lt;value&gt;3000&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;maxIdle&lt;/name&gt;
&lt;value&gt;100&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;maxActive&lt;/name&gt;
&lt;value&gt;10&lt;/value&gt;
&lt;/parameter&gt;
&lt;/ResourceParams&gt;
&lt;/Context&gt;</pre>
<p>我们在这个例子中要配置的上下文叫做<tt class="literal">quickstart</tt>，它位于<tt class="literal">TOMCAT/webapp/quickstart</tt>目录下。如果要访问这个应用程序,在你的浏览器中输入<tt class="literal">http://localhost:8080/quickstart</tt>就可以了(当然，在后面加上在你的<tt class="literal">web.xml</tt>文件中配置好你的servlet)。你现在可以创建一个只含有空<tt class="literal">process()</tt>的简单servlet了。 </p>
<p>Tomcat现在通过JNDI的方式：<tt class="literal">java:comp/env/jdbc/quickstart</tt>来提供连接。如果你在配置连接池遇到问题，请查阅Tomcat文档。如果你遇到了JDBC驱动所报的exception出错信息，请在没有Hibernate的环境下，先测试JDBC连接池本身是否配置正确。Tomcat和JDBC的配置教程可以在Web上查到。 </p>
<p>下一步就是配置Hibernate。首先Hibernate必须知道它如何获得JDBC连接，在这里我们使用基于XML格式的Hibernate配置文件。当然使用properties文件的进行配置，但缺少一些XML语法的特性。这个XML配置文件必须放在上下文类路径(<tt class="literal">WEB-INF/classes</tt>)下面，命名为<tt class="literal">hibernate.cfg.xml</tt>: </p>
<pre class="programlisting">&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&gt;
&lt;hibernate-configuration&gt;
&lt;session-factory&gt;
&lt;property name="connection.datasource"&gt;java:comp/env/jdbc/quickstart&lt;/property&gt;
&lt;property name="show_sql"&gt;false&lt;/property&gt;
&lt;property name="dialect"&gt;org.hibernate.dialect.PostgreSQLDialect&lt;/property&gt;
&lt;!-- Mapping files --&gt;
&lt;mapping resource="Cat.hbm.xml"/&gt;
&lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;</pre>
<p>在这里我们关闭了SQL命令的log，同时告诉Hibernate使用哪种SQL数据库用语(Dialet)，以及如何得到JDBC连接（通过 Tomcat声明绑定的JNDI地址）。Dialet是必需配置的，因为不同的数据库都和"SQL标准"有一些出入。不用担心，Hibernate会替你处理这些差异，Hibernate支持所有主流的商业和开放源代码数据库。 </p>
<p><tt class="literal">SessionFactory</tt>是Hibernate的的一个概念，表示对应一个数据存储源。通过创建多个XML配置文件并也在你的程序中创建多个<tt class="literal">Configuration</tt>和<tt class="literal">SessionFactory</tt>对象，就可以支持多个数据库了。 </p>
<p>在<tt class="literal">hibernate.cfg.xml</tt>中的最后一个元素声明了<tt class="literal">Cat.hbm.xml</tt>，这是一个Hibernate XML映射文件，对应于持久化类<tt class="literal">Cat</tt>。这个文件包含了把<tt class="literal">Cat</tt> POJO类映射到数据库表（或多个数据库表）的元数据。我们稍后就回来看这个文件。下一步让我们先编写这个POJO类，然后在声明它的映射元数据。 </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">1.2.&nbsp;第一个持久化类</h2>
<p>Hibernate使用简单的Java对象(Plain Old Java Objects ,就是POJOs,有时候也称作Plain Ordinary Java Objects）这种编程模型来进行持久化。一个POJO很像JavaBean,通过getter和setter方法访问其属性，对外则隐藏了内部实现的细节(假若需要的话,Hibernate也可以直接访问其属性字段)。 </p>
<pre class="programlisting">package org.hibernate.examples.quickstart;
public class Cat {
private String id;
private String name;
private char sex;
private float weight;
public Cat() {
}
public String getId() {
return id;
}
private void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
}</pre>
<p>Hibernate对属性使用的类型不加任何限制。所有的Java JDK类型和原始类型（比如<tt class="literal">String</tt>,<tt class="literal">char</tt>和<tt class="literal">Date</tt>)都可以被映射，也包括Java 集合（Java collections framework)中的类。你可以把它们映射成为值，值集合，或者与其他实体类相关联。<tt class="literal">id</tt>是一个特殊的属性，代表了这个类的数据库标识符(主键)，对于类似于<tt class="literal">Cat</tt>这样的实体类我们强烈建议使用。Hibernate也可以使用内部标识符，但这样我们会失去一些程序架构方面的灵活性。 </p>
<p>持久化类不需要实现什么特别的接口，也不需要从一个特别的持久化根类继承下来。Hibernate也不需要使用任何编译期处理，比如字节码增强操作，它独立的使用Java反射机制和运行时类增强（通过CGLIB）。所以不依赖于Hibernate，我们就可以把POJO的类映射成为数据库表。 </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">1.3.&nbsp;映射cat</h2>
<p><tt class="literal">Cat.hbm.xml</tt>映射文件包含了对象/关系映射（O/R Mapping）所需的元数据。元数据包含持久化类的声明和属性到数据库的映射（指向字段和其他实体的外键关联）。 </p>
<pre class="programlisting">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;
&lt;hibernate-mapping&gt;
&lt;class name="org.hibernate.examples.quickstart.Cat" table="CAT"&gt;
&lt;!-- A 32 hex character is our surrogate key. It's automatically
generated by Hibernate with the UUID pattern. --&gt;
&lt;id name="id" type="string" unsaved-value="null" &gt;
&lt;column name="CAT_ID" sql-type="char(32)" not-null="true"/&gt;
&lt;generator class="uuid.hex"/&gt;
&lt;/id&gt;
&lt;!-- A cat has to have a name, but it shouldn' be too long. --&gt;
&lt;property name="name"&gt;
&lt;column name="NAME" length="16" not-null="true"/&gt;
&lt;/property&gt;
&lt;property name="sex"/&gt;
&lt;property name="weight"/&gt;
&lt;/class&gt;
&lt;/hibernate-mapping&gt;</pre>
<p>每个持久化类都应该有一个标识属性（实际上，这个类只代表实体，而不是独立的值类型类，后者会被映射称为实体对象中的一个组件）。这个属性用来区分持久化对象：如果<tt class="literal">catA.getId().equals(catB.getId())</tt>结果是true的话，这两个Cat就是相同的。这个概念称为<span class="emphasis"><em>数据库标识</em></span>。Hiernate 附带了几种不同的标识符生成器，用于不同的场合（包括数据库本地的顺序(sequence)生成器、hi/lo高低位标识模式、和程序自己定义的标识符）。我们在这里使用UUID生成器（只在测试时建议使用，如果使用数据库自己生成的整数类型的键值更好），并指定<tt class="literal">CAT</tt>表中的<tt class="literal">CAT_ID</tt>字段（作为表的主键）存放生成的标识值。 </p>
<p><tt class="literal">Cat</tt>的其他属性都映射到同一个表的字段。对<tt class="literal">name</tt>属性来说，我们把它显式地声明映射到一个数据库字段。如果数据库schema是通过由映射声明使用Hibernate的<span class="emphasis"><em>SchemaExport</em></span>工具自动生成的（作为SQL DDL指令）的话，这就特别有用。所有其它的属性都用Hibernate的默认值映射，大多数情况你都会这样做。数据库中的<tt class="literal">CAT</tt>表看起来是这样的： </p>
<pre class="programlisting"> Column |         Type          | Modifiers
--------+-----------------------+-----------
cat_id | character(32)         | not null
name   | character varying(16) | not null
sex    | character(1)          |
weight | real                  |
Indexes: cat_pkey primary key btree (cat_id)</pre>
<p>你现在可以在你的数据库中手工创建这个表了，如果你需要使用<tt class="literal">hbm2ddl</tt>工具把这个步骤自动化，请参阅<a title="第&nbsp;20&nbsp;章&nbsp;工具箱指南" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/toolsetguide.html">第&nbsp;20&nbsp;章 <em>工具箱指南</em></a>。这个工具能够创建完整的SQL DDL，包括表定义，自定义的字段类型约束，惟一约束和索引。 </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">1.4.&nbsp;与Cat同乐</h2>
<p>我们现在可以开始Hibernate的<tt class="literal">Session</tt>了。它是一个<span class="emphasis"><em>持久化管理器</em></span>，我们通过它来从数据库中存取<tt class="literal">Cat</tt>。首先，我们要从<tt class="literal">SessionFactory</tt>中获取一个<tt class="literal">Session</tt>（Hibernate的工作单元）。 </p>
<pre class="programlisting">SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory();</pre>
<p>通过对<tt class="literal">configure()</tt>的调用来装载<tt class="literal">hibernate.cfg.xml</tt>配置文件,并初始化成一个<tt class="literal">Configuration</tt>实例。 在创建 <tt class="literal">SessionFactory</tt><span class="emphasis"><em>之前</em></span>（它是不可变的），你可以访问<tt class="literal">Configuration</tt>来设置其他属性（甚至修改映射的元数据）。我们应该在哪儿创建<tt class="literal">SessionFactory</tt>，在我们的程序中又如何访问它呢？ <tt class="literal">SessionFactory</tt>通常只是被初始化一次，比如说通过一个<span class="emphasis"><em>load-on-startup</em></span> servlet的来初始化。这意味着你不应该在serlvet中把它作为一个实例变量来持有，而应该放在其他地方。进一步的说，我们需要使用<span class="emphasis"><em>单例（Singleton）</em></span>模式，我们才能更容易的在程序中访问<tt class="literal">SessionFactory</tt>。下面的方法就同时解决了两个问题：对<tt class="literal">SessionFactory</tt>的初始配置与便捷使用。 </p>
<p>我们实现一个<tt class="literal">HibernateUtil</tt>辅助类： </p>
<pre class="programlisting">import org.hibernate.*;
import org.hibernate.cfg.*;
public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession()  {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() {
Session s = (Session) session.get();
if (s != null)
s.close();
session.set(null);
}
}</pre>
<p>这个类不但在它的静态初始器中使用了<tt class="literal">SessionFactory</tt>，还使用了一个<tt class="literal">ThreadLocal</tt>变量来保存<tt class="literal">Session</tt>做为当前工作线程。在你使用这个辅助类之前，请确保你理解了thread-local变量这个Java概念。你可以在<tt class="literal">CaveatEmptor</tt>(http://caveatemptor.hibernate.org/)上找到一个更加复杂和强大的 <tt class="literal">HibernateUtil</tt>。 </p>
<p><tt class="literal">SessionFactory</tt>是安全线程，可以由很多线程并发访问并获取到<tt class="literal">Sessions</tt>。单个<tt class="literal">Session</tt>不是安全线程对象，它只代表与数据库之间的一次操作。<tt class="literal">Session</tt>通过<tt class="literal">SessionFactory</tt>获得并在所有的工作完成后关闭。在你servlet的<tt class="literal">process()</tt>中可以象是这么写的(省略了异常情况处理): </p>
<pre class="programlisting">Session session = HibernateUtil.currentSession();
Transaction tx= session.beginTransaction();
Cat princess = new Cat();
princess.setName("Princess");
princess.setSex('F');
princess.setWeight(7.4f);
session.save(princess);
tx.commit();
HibernateUtil.closeSession();</pre>
<p>在一个<tt class="literal">Session</tt>中，每个数据库操作都是在一个事务(transaction)中进行的，这样就可以隔离开不同的操作（甚至包括只读操作）。我们使用Hibernate的<tt class="literal">Transaction</tt> API来从底层的事务策略中（本例中是JDBC事务）脱身出来。这样，我们就不需要更改任何源代码，就可以把我们的程序部署到一个由容器管理事务的环境中去（使用JTA）。 </p>
<p>这样你就可以随心所欲的多次调用<tt class="literal">HibernateUtil.currentSession();</tt>，你每次都会得到同一个当前线程的<tt class="literal">Session</tt>。不管是在你的servlet代码中，或者在servlet filter中还是在HTTP结果返回之前，你都必须确保这个<tt class="literal">Session</tt>在你的数据库访问工作完成后关闭。这样做还有一个好处就是可以容易的使用延迟装载（lazy initialization）：<tt class="literal">Session</tt>在渲染view层的时候仍然打开着的，所以你在遍历当前对象图的时候可以装载所需的对象。 </p>
<p>Hibernate有不同的方法用来从数据库中取回对象。最灵活的方式就是使用Hibernate查询语言(HQL),这是一种容易学习的语言，是对SQL的面向对象的强大扩展。 </p>
<pre class="programlisting">Transaction tx= session.beginTransaction();
Query query = session.createQuery("select c from Cat as c where c.sex = :sex");
query.setCharacter("sex", 'F');
for (Iterator it = query.iterate(); it.hasNext();) {
Cat cat = (Cat) it.next();
out.println("Female Cat: " + cat.getName() );
}
tx.commit();</pre>
<p>Hibernate也提供一种面向对象的<span class="emphasis"><em>按条件查询</em></span>API，可以执行简洁安全类型的查询。当然，Hibernate在所有与数据库的交互中都使用<tt class="literal">PrepatedStatement</tt>和参数绑定。你也可以使用Hibernate的直接SQL查询特性，或者在特殊情况下从<tt class="literal">Session</tt>获取一个原始的JDBC连接。 </p>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both"><a name="quickstart-summary"></a>1.5.&nbsp;结语</h2>
<p>在这个短小的教程中，我们对Hibernate的浅尝即止。请注意我们没有在例子中包含任何servlet相关代码。你必须自行编写servlet，并插入合适你的Hibernate代码。 </p>
<p>请记住Hibernate作为一个数据库访问层，是与你的程序紧密相关的。通常情况下，所有其他层次都依赖持久机制。请确信你理解了这种设计的内涵。 </p>
<p>若希望学习更复杂的例子,请参阅http://caveatemptor.hibernate.org/ 。在 http://www.hibernate.org/Documentation 也可以得到其他教程的链接。 </p>
</div><img src ="http://www.blogjava.net/mikecheers/aggbug/182904.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikecheers/" target="_blank">Mike Cheers</a> 2008-02-29 13:53 <a href="http://www.blogjava.net/mikecheers/articles/182904.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>前言</title><link>http://www.blogjava.net/mikecheers/articles/182900.html</link><dc:creator>Mike Cheers</dc:creator><author>Mike Cheers</author><pubDate>Fri, 29 Feb 2008 05:42:00 GMT</pubDate><guid>http://www.blogjava.net/mikecheers/articles/182900.html</guid><wfw:comment>http://www.blogjava.net/mikecheers/comments/182900.html</wfw:comment><comments>http://www.blogjava.net/mikecheers/articles/182900.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikecheers/comments/commentRss/182900.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikecheers/services/trackbacks/182900.html</trackback:ping><description><![CDATA[<h2 class="title">前言</h2>
<p>WARNING! This is a translated version of the English Hibernate reference documentation. The translated version might not be up to date! However, the differences should only be very minor. Consult the English reference documentation if you are missing information or encounter a translation error. If you like to contribute to a particular translation, contact us on the Hibernate developer mailing list. </p>
<p>Translator(s): Xiaogang Cao &lt;caoxg@yahoo.com&gt; </p>
<p>在今日的企业环境中，把面向对象的软件和关系数据库一起使用可能是相当麻烦、浪费时间的。Hibernate是一个面向Java环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping (ORM))这个术语表示一种技术，用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。 </p>
<p>Hibernate不仅仅管理Java类到数据库表的映射（包括Java数据类型到SQL数据类型的映射），还提供数据查询和获取数据的方法，可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。 </p>
<p>Hibernate的目标是对于开发者通常的数据持久化相关的编程任务，解放其中的95%。对于以数据为中心的程序来说,它们往往只在数据库中使用存储过程来实现商业逻辑,Hibernate可能不是最好的解决方案;对于那些在基于Java的中间层应用中，它们实现面向对象的业务模型和商业逻辑的应用， Hibernate是最有用的。不管怎样，Hibernate一定可以帮助你消除或者包装那些针对特定厂商的SQL代码，并且帮你把结果集从表格式的表示形式转换到一系列的对象去。 </p>
<p>如果你对Hibernate和对象/关系数据库映射还是个新手，或者甚至对Java也不熟悉，请按照下面的步骤来学习。 </p>
<div class="orderedlist">
<ol type="1">
    <li>
    <p>阅读这个30分钟就可以结束的<a title="第&nbsp;1&nbsp;章&nbsp;在Tomcat中快速上手" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/quickstart.html">第&nbsp;1&nbsp;章 <em>在Tomcat中快速上手</em></a>，它使用Tomcat。 </p>
    <li>
    <p>阅读<a title="第&nbsp;2&nbsp;章&nbsp;架构(Architecture)" href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/architecture.html">第&nbsp;2&nbsp;章 <em>架构(Architecture)</em></a>来理解Hibernate可以使用的环境。 </p>
    <li>
    <p>查看Hibernate发行包中的<tt class="literal">eg/</tt>目录，里面有一个简单的独立运行的程序。把你的JDBC驱动拷贝到<tt class="literal">lib/</tt>目录下，修改一下<tt class="literal">src/hibernate.properties</tt>,指定其中你的数据库的信息。进入命令行，切换到你的发行包的目录，输入<tt class="literal">ant eg</tt>(使用了Ant），或者在Windows操作系统中使用<tt class="literal">build eg</tt>。 </p>
    <li>
    <p>把这份参考文档作为你学习的主要信息来源。 </p>
    <li>
    <p>在Hibernate 的网站上可以找到经常提问的问题与解答(FAQ)。 </p>
    <li>
    <p>在Hibernate网站上还有第三方的演示、示例和教程的链接。 </p>
    <li>
    <p>Hibernate网站的&#8220;社区(Community Area)&#8221;是讨论关于设计模式以及很多整合方案(Tomcat, JBoss, Struts, EJB,等等)的好地方。 </p>
    </li>
</ol>
</div>
<p>如果你有问题，请使用Hibernate网站上链接的用户论坛。我们也提供一个JIRA问题追踪系统，来搜集bug报告和新功能请求。如果你对开发Hibernate有兴趣，请加入开发者的邮件列表。 （译者注:http://www.redsaga.com 和一个非官方的由爱好者设立的中文论坛：http://forum.hibernate.org.cn 都随时欢迎您的访问。） </p>
<p>商业开发、产品支持和Hibernate培训可以通过JBoss Inc.获得。（请查阅：http://www.hibernate.org/SupportTraining/）。Hibernate是一个包含于 JBoss Professional Open Source产品套件的项目。 </p>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">1.&nbsp;翻译说明</h2>
<p>本文档的翻译是在网络上协作进行的，也会不断根据Hibernate的升级进行更新。提供此文档的目的是为了减缓学习Hibernate的坡度，而非代替原文档。我们建议所有有能力的读者都直接阅读英文原文。若您对翻译有异议，或发现翻译错误，敬请不吝赐教，报告到如下email地址：caoxg at redsaga.com </p>
<p>Hibernate版本3的翻译由满江红(redsaga)翻译团队集体进行，同时也是一次大规模网络翻译的试验。在两周的时间内，就完成了两百多页文档的翻译，这一成果是由十几位网友集体努力完成的。通过这次翻译，我们也有了一套完整的流程，从初译、技术审核一直到文字审核、发布。我们的翻译团队还会继续翻译其他优秀的Java开源资料，敬请期待。 </p>
<div class="table"><a name="redsaga-translate-team"></a>
<p class="title"><strong>表&nbsp;1.&nbsp; Hibernate v3翻译团队 </strong></p>
<table summary="                Hibernate v3翻译团队&#10;            " border="1">
    <colgroup>
    <col>
    <col>
    <col>
    <col>
    <col></colgroup>
    <thead>
        <tr>
            <th align="center">序号 </th>
            <th align="center">标题 </th>
            <th align="center">中文标题 </th>
            <th align="center">翻译 </th>
            <th align="center">一审 </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>#1</td>
            <td>Quickstart with Tomcat(*)</td>
            <td>在Tomcat中快速上手</td>
            <td>caoxiaogang</td>
            <td>zoujm</td>
        </tr>
        <tr>
            <td>#2</td>
            <td>Architecture</td>
            <td>架构</td>
            <td>Hilton(BJUG)</td>
            <td>厌倦发呆</td>
        </tr>
        <tr>
            <td>#3</td>
            <td>Configuration</td>
            <td>配置</td>
            <td>Goncha</td>
            <td>robbin</td>
        </tr>
        <tr>
            <td>#4</td>
            <td>Persistent Classes(*)</td>
            <td>持久化类</td>
            <td>caoxiaogang</td>
            <td>mochow</td>
        </tr>
        <tr>
            <td>#5</td>
            <td>Basic O/R Mapping</td>
            <td>对象/关系数据库映射基础(上)</td>
            <td>moxie</td>
            <td>goncha</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>对象/关系数据库映射基础(下)</td>
            <td>inter_dudu</td>
            <td>vincent</td>
        </tr>
        <tr>
            <td>#6</td>
            <td>Collection Mapping(*)</td>
            <td>集合类映射</td>
            <td>caoxiaogang</td>
            <td>robbin</td>
        </tr>
        <tr>
            <td>#7</td>
            <td>Association Mappings</td>
            <td>关联关系映射</td>
            <td>Robbin</td>
            <td>devils.advocate</td>
        </tr>
        <tr>
            <td>#8</td>
            <td>Component Mapping(*)</td>
            <td>组件映射</td>
            <td>caoxiaogang</td>
            <td>robbin</td>
        </tr>
        <tr>
            <td>#9</td>
            <td>Inheritance Mappings</td>
            <td>继承映射</td>
            <td>morning(BJUG)</td>
            <td>mochow</td>
        </tr>
        <tr>
            <td>#10</td>
            <td>Working with objects</td>
            <td>与对象共事</td>
            <td>程广楠</td>
            <td>厌倦发呆</td>
        </tr>
        <tr>
            <td>#11</td>
            <td>Transactions And Concurrency</td>
            <td>事务和并发</td>
            <td>Robbin</td>
            <td>mochow</td>
        </tr>
        <tr>
            <td>#12</td>
            <td>Interceptors and events</td>
            <td>继承映射</td>
            <td>七彩狼(BJUG)</td>
            <td>厌倦发呆</td>
        </tr>
        <tr>
            <td>#13</td>
            <td>Batch processing</td>
            <td>批量处理</td>
            <td>Kingfish(BJUG)</td>
            <td>厌倦发呆</td>
        </tr>
        <tr>
            <td>#14</td>
            <td>HQL: The Hibernate Query Language</td>
            <td>HQL: Hibernate查询语言</td>
            <td>郑浩(BJUG)</td>
            <td>zhengshuai</td>
        </tr>
        <tr>
            <td>#15</td>
            <td>Criteria Queries</td>
            <td>条件查询</td>
            <td>nemo(BJUG)</td>
            <td>zhengshuai</td>
        </tr>
        <tr>
            <td>#16</td>
            <td>Native SQL</td>
            <td>Native SQL查询</td>
            <td>似水流年</td>
            <td>zoujm</td>
        </tr>
        <tr>
            <td>#17</td>
            <td>Filters</td>
            <td>过滤数据</td>
            <td>冰云(BJUG)</td>
            <td>goncha</td>
        </tr>
        <tr>
            <td>#18</td>
            <td>XML Mapping</td>
            <td>XML映射</td>
            <td>edward(BJUG)</td>
            <td>goncha</td>
        </tr>
        <tr>
            <td>#19</td>
            <td>Improving performance</td>
            <td>性能提升</td>
            <td>Wangjinfeng</td>
            <td>robbin</td>
        </tr>
        <tr>
            <td>#20</td>
            <td>Toolset Guide(*)</td>
            <td>工具箱指南</td>
            <td>caoxiaogang</td>
            <td>robbin</td>
        </tr>
        <tr>
            <td>#21</td>
            <td>Example: Parent/Child(*)</td>
            <td>示例：父子关系</td>
            <td>caoxiaogang</td>
            <td>devils.advocate</td>
        </tr>
        <tr>
            <td>#22</td>
            <td>Example: Weblog Application(*)</td>
            <td>示例：Weblog 应用程序</td>
            <td>caoxiaogang</td>
            <td>devils.advocate</td>
        </tr>
        <tr>
            <td>#23</td>
            <td>Example: Various Mappings</td>
            <td>示例：多种映射</td>
            <td>shidu(BJUG)</td>
            <td>冰云</td>
        </tr>
        <tr>
            <td>#24</td>
            <td>Best Practices(*)</td>
            <td>最佳实践</td>
            <td>caoxiaogang</td>
            <td>冰云</td>
        </tr>
    </tbody>
</table>
</div>
<p>参与二审的人员有:Robbin,linxin. </p>
<p>关于我们 </p>
<div class="variablelist">
<dl>
<dt><span class="term">满江红.开源, http://www.redsaga.com</span>
<dd>
<p>致力于Java开放源代码在中国的传播与发展。目前有两个团队，&#8220;OpenDoc团队&#8221;与&#8220;翻译团队&#8221;。OpenDoc团队已经推出包括 Hibernate、iBatis、Spring、WebWork的多份开放文档，并在Hibernate开放文档基础上扩充出版了原创作品：《深入浅出 Hibernate》，敬请支持。 </p>
<dt><span class="term">北京Java用户组, http://www.bjug.org</span>
<dd>
<p>我们的口号是&#8220;Communication and Contribution&#8221;。我们在北京定期举行集会与交流，内容与录音可以从网站上下载。 </p>
<dt><span class="term">Java视线, http://www.javaeye.com</span>
<dd>
<p>前身为Hibernate中文论坛，现在已发展为包括Java,.NET，python等各种技术的高质量论坛。 </p>
</dd></dl></div>
</div>
<div class="sect1" lang="zh-cn">
<h2 class="title" style="clear: both">2.&nbsp;版权声明</h2>
<p>Hibernate英文文档属于Hibernate发行包的一部分，遵循LGPL协议。本翻译版本同样遵循LGPL协议。参与翻译的译者一致同意放弃除署名权外对本翻译版本的其它权利要求。 </p>
<p>您可以自由链接、下载、传播此文档，或者放置在您的网站上，甚至作为产品的一部分发行。但前提是必须保证全文完整转载，包括完整的版权信息和作译者声明。这里&#8220;完整&#8221;的含义是，不能进行任何删除/增添/注解。若有删除/增添/注解，必须逐段明确声明那些部分并非本文档的一部分。 </p>
</div><img src ="http://www.blogjava.net/mikecheers/aggbug/182900.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikecheers/" target="_blank">Mike Cheers</a> 2008-02-29 13:42 <a href="http://www.blogjava.net/mikecheers/articles/182900.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>