241 lines
12 KiB
XML
241 lines
12 KiB
XML
<chapter id="architecture">
|
||
|
||
<title>体系结构(Architecture)</title>
|
||
<sect1 id="architecture-overview" revision="1">
|
||
<title>概况(Overview)</title>
|
||
|
||
<para>
|
||
一个非常简要的Hibernate体系结构的概要图:
|
||
</para>
|
||
|
||
<mediaobject>
|
||
<imageobject role="fo">
|
||
<imagedata fileref="images/overview.svg" format="SVG" align="center"/>
|
||
</imageobject>
|
||
<imageobject role="html">
|
||
<imagedata fileref="../shared/images/overview.gif" format="GIF" align="center"/>
|
||
</imageobject>
|
||
</mediaobject>
|
||
|
||
<para>
|
||
从这个图可以看出,Hibernater使用数据库和配置信息来为应用程序提供持久化服务(以及持久的对象)。
|
||
</para>
|
||
|
||
<para>
|
||
我们来更详细地看一下Hibernate运行时体系结构。由于Hibernate非常灵活,且支持数种应用方案,
|
||
所以我们这只描述一下两种极端的情况。“轻型”的体系结构方案,要求应用程序提供自己的JDBC
|
||
连接并管理自己的事务。这种方案使用了Hibernate API的最小子集:
|
||
</para>
|
||
|
||
<mediaobject>
|
||
<imageobject role="fo">
|
||
<imagedata fileref="images/lite.svg" format="SVG" align="center"/>
|
||
</imageobject>
|
||
<imageobject role="html">
|
||
<imagedata fileref="../shared/images/lite.gif" format="GIF" align="center"/>
|
||
</imageobject>
|
||
</mediaobject>
|
||
|
||
<para>
|
||
“全面解决”的体系结构方案,将应用层从底层的JDBC/JTA API中抽象出来,而让Hibernate来处理这些细节。
|
||
</para>
|
||
|
||
<mediaobject>
|
||
<imageobject role="fo">
|
||
<imagedata fileref="images/full_cream.svg" format="SVG" align="center"/>
|
||
</imageobject>
|
||
<imageobject role="html">
|
||
<imagedata fileref="../shared/images/full_cream.gif" format="GIF" align="center"/>
|
||
</imageobject>
|
||
</mediaobject>
|
||
|
||
<para>
|
||
图中各个对象的定义如下:
|
||
|
||
<variablelist spacing="compact">
|
||
<varlistentry>
|
||
<term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
|
||
<listitem>
|
||
<para>
|
||
针对单个数据库映射关系经过编译后的内存镜像,它也是线程安全的(不可变)。
|
||
它是生成<literal>Session</literal>的工厂,本身要用到<literal>ConnectionProvider</literal>。
|
||
该对象可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Session (<literal>org.hibernate.Session</literal>)</term>
|
||
<listitem>
|
||
<para>
|
||
表示应用程序与持久储存层之间交互操作的一个单线程对象,此对象生存期很短。
|
||
其隐藏了JDBC连接,也是<literal>Transaction</literal>的工厂。
|
||
其会持有一个针对持久化对象的必选(第一级)缓存,在遍历对象图或者根据持久化标识查找对象时会用到。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>持久的对象及其集合</term>
|
||
<listitem>
|
||
<para>
|
||
带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。
|
||
这些对象可以是普通的JavaBeans/POJO,唯一特殊的是他们正与(仅仅一个)<literal>Session</literal>相关联。
|
||
这个<literal>Session</literal>被关闭的同时,这些对象也会脱离持久化状态,可以被应用程序的任何层自由使用。
|
||
(例如,用作跟表示层打交道的数据传输对象data transfer object。)
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>瞬态(transient)以及脱管(detached)的对象及其集合</term>
|
||
<listitem>
|
||
<para>
|
||
持久类的没有与<literal>Session</literal>相关联的实例。
|
||
他们可能是在被应用程序实例化后,尚未进行持久化的对象。
|
||
也可能是因为实例化他们的<literal>Session</literal>已经被关闭而脱离持久化的对象。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>事务Transaction (<literal>org.hibernate.Transaction</literal>)</term>
|
||
<listitem>
|
||
<para>
|
||
(可选的)应用程序用来指定原子操作单元范围的对象,它是单线程的,生存期很短。
|
||
它通过抽象将应用从底层具体的JDBC、JTA以及CORBA事务隔离开。
|
||
某些情况下,一个<literal>Session</literal>之内可能包含多个<literal>Transaction</literal>对象。
|
||
尽管是否使用该对象是可选的,但是事务边界的开启与关闭(无论是使用底层的API还是使用<literal>Transaction</literal>对象)是必不可少的。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
|
||
<listitem>
|
||
<para>
|
||
(可选的)生成JDBC连接的工厂(同时也起到连接池的作用)。
|
||
它通过抽象将应用从底层的<literal>Datasource</literal>或<literal>DriverManager</literal>隔离开。
|
||
仅供开发者扩展/实现用,并不暴露给应用程序使用。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
|
||
<listitem>
|
||
<para>
|
||
(可选的)生成<literal>Transaction</literal>对象实例的工厂。
|
||
仅供开发者扩展/实现用,并不暴露给应用程序使用。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>扩展接口</emphasis></term>
|
||
<listitem>
|
||
<para>
|
||
Hibernate提供了很多可选的扩展接口,你可以通过实现它们来定制你的持久层的行为。
|
||
具体请参考API文档。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</para>
|
||
|
||
<para>
|
||
在一个“轻型”的体系结构中,应用程序可能绕过
|
||
<literal>Transaction</literal>/<literal>TransactionFactory</literal> 以及
|
||
<literal>ConnectionProvider</literal> 等API直接跟JTA或JDBC打交道。
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 id="architecture-states" revision="1">
|
||
<title>实例状态</title>
|
||
<para>
|
||
一个持久化类的实例可能处于三种不同状态中的某一种。
|
||
这三种状态的定义则与所谓的<emphasis>持久化上下文(persistence context)</emphasis>有关。
|
||
Hibernate的<literal>Session</literal>对象就是这个所谓的持久化上下文:
|
||
</para>
|
||
|
||
<variablelist spacing="compact">
|
||
<varlistentry>
|
||
<term>瞬态(transient)</term>
|
||
<listitem>
|
||
<para>
|
||
该实例从未与任何持久化上下文关联过。它没有持久化标识(相当于主键)。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>持久(persistent)</term>
|
||
<listitem>
|
||
<para>
|
||
实例目前与某个持久化上下文有关联。
|
||
它拥有持久化标识(相当于主键),并且可能在数据库中有一个对应的行。
|
||
对于某一个特定的持久化上下文,Hibernate<emphasis>保证</emphasis>持久化标识与Java标识(其值代表对象在内存中的位置)等价。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>脱管(detached)</term>
|
||
<listitem>
|
||
<para>
|
||
实例曾经与某个持久化上下文发生过关联,不过那个上下文被关闭了,
|
||
或者这个实例是被序列化(serialize)到这个进程来的。
|
||
它拥有持久化标识,并且在数据库中可能存在一个对应的行。
|
||
对于脱管状态的实例,Hibernate不保证任何持久化标识和Java标识的关系。
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect1>
|
||
|
||
<sect1 id="architecture-jmx" revision="1">
|
||
<title>JMX整合</title>
|
||
|
||
<para>
|
||
JMX是管理Java组件(Java components)的J2EE规范。 Hibernate 可以通过一个JMX标准服务来管理。
|
||
在这个发行版本中,我们提供了一个MBean接口的实现,即
|
||
<literal>org.hibernate.jmx.HibernateService</literal>。
|
||
</para>
|
||
|
||
<para>
|
||
想要看如何在JBoss应用服务器上将Hibernate部署为一个JMX服务的例子,您可以参考JBoss用户指南。
|
||
我们现在说一下在Jboss应用服务器上,使用JMX来部署Hibernate的好处:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
<emphasis>Session管理:</emphasis> Hibernate的<literal>Session</literal>对象的生命周期可以
|
||
自动跟一个JTA事务边界绑定。这意味着你无需手工开关<literal>Session</literal>了, 这项
|
||
工作会由JBoss EJB 拦截器来完成。你再也不用担心你的代码中的事务边界了(除非你想利用Hibernate提供
|
||
的<literal>Transaction</literal> API来自己写一个便于移植的的持久层)。
|
||
你现在要通过 <literal>HibernateContext</literal>来操作<literal>Session</literal>了。
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
<emphasis>HAR 部署:</emphasis> 通常情况下,你会使用JBoss的服务部署描述符(在EAR或/和SAR文件中)来部署Hibernate JMX服务。
|
||
这种部署方式支持所有常见的Hibernate <literal>SessionFactory</literal>的配置选项。
|
||
不过,你需在部署描述符中,列出你所有的映射文件的名字。如果你使用HAR部署方式, JBoss
|
||
会自动探测出你的HAR文件中所有的映射文件。
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
这些选项更多的描述,请参考JBoss 应用程序用户指南。
|
||
</para>
|
||
|
||
<para>
|
||
将Hibernate以部署为JMX服务的另一个好处,是可以查看Hibernate的运行时统计信息。参看
|
||
<xref linkend="configuration-optional-statistics"/>.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 id="architecture-jca" revision="1">
|
||
<title>对JCA的支持</title>
|
||
<para>
|
||
Hibernate也可以被配置为一个JCA连接器(JCA connector)。更多信息请参看网站。
|
||
请注意,Hibernate对JCA的支持,仍处于实验性质。
|
||
</para>
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|