<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    【永恒的瞬間】
    ?Give me hapy ?

    第 4 章  配置

    由于Hibernate是為了能在各種不同環境下工作而設計的, 因此存在著大量的配置參數. 幸運的是多數配置參數都 有比較直觀的默認值, 并有隨Hibernate一同分發的配置樣例hibernate.properties (位于etc/)來展示各種配置選項. 所需做的僅僅是將這個樣例文件復制到類路徑 (classpath)下做一些自定義的修改.

    4.1.  可編程的配置方式

    一個org.hibernate.cfg.Configuration實例代表了一個應用程序中Java類型 到SQL數據庫映射的完整集合. Configuration被用來構建一個(不可變的 (immutable))SessionFactory. 映射定義則由不同的XML映射定義文件編譯而來.

    你可以直接實例化Configuration來獲取一個實例,并為它指定XML映射定義 文件. 如果映射定 義文件在類路徑(classpath)中, 請使用addResource():

    Configuration cfg = new Configuration()
    .addResource("Item.hbm.xml")
    .addResource("Bid.hbm.xml");

    一個替代方法(有時是更好的選擇)是,指定被映射的類,讓Hibernate幫你尋找映射定義文件:

    Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class);

    Hibernate將會在類路徑(classpath)中尋找名字為 /org/hibernate/auction/Item.hbm.xml/org/hibernate/auction/Bid.hbm.xml映射定義文件. 這種方式消除了任何對文件名的硬編碼(hardcoded).

    Configuration也允許你指定配置屬性:

    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");

    當然這不是唯一的傳遞Hibernate配置屬性的方式, 其他可選方式還包括:

    1. 傳一個java.util.Properties實例給 Configuration.setProperties().

    2. hibernate.properties放置在類路徑(classpath)的根目錄下 (root directory).

    3. 通過java -Dproperty=value來設置系統 (System)屬性.

    4. hibernate.cfg.xml中加入元素 <property> (稍后討論).

    如果想盡快體驗Hbernate, hibernate.properties是最簡單的方式.

    Configuration實例是一個啟動期間(startup-time)的對象, 一旦SessionFactory創建完成它就被丟棄了.

    4.2.  獲得SessionFactory

    當所有映射定義被Configuration解析后, 應用程序必須獲得一個用于構造Session實例的工廠. 這個工廠將被應用程序的所有線程共享:

    SessionFactory sessions = cfg.buildSessionFactory();

    Hibernate允許你的應用程序創建多個SessionFactory實例. 這對 使用多個數據庫的應用來說很有用.

    4.3.  JDBC連接

    通常你希望SessionFactory來為你創建和緩存(pool)JDBC連接. 如果你采用這種方式, 只需要如下例所示那樣,打開一個Session:

    Session session = sessions.openSession(); // open a new Session

    一旦你需要進行數據訪問時, 就會從連接池(connection pool)獲得一個JDBC連接.

    為了使這種方式工作起來, 我們需要向Hibernate傳遞一些JDBC連接的屬性. 所有Hibernate屬性的名字和語義都在org.hibernate.cfg.Environment中定義. 我們現在將描述JDBC連接配置中最重要的設置.

    如果你設置如下屬性,Hibernate將使用java.sql.DriverManager來獲得(和緩存)JDBC連接 :

    表 4.1.  Hibernate JDBC屬性

    屬性名 用途
    hibernate.connection.driver_class jdbc驅動類
    hibernate.connection.url jdbc URL
    hibernate.connection.username 數據庫用戶
    hibernate.connection.password 數據庫用戶密碼
    hibernate.connection.pool_size 連接池容量上限數目

    但Hibernate自帶的連接池算法相當不成熟. 它只是為了讓你快些上手,不適合用于產品系統或性能測試中。 出于最佳性能和穩定性考慮你應該使用第三方的連接池。只需要連接池的特定設置替換 hibernate.connection.pool_size。這將關閉Hibernate自帶的連接池. 例如, 你可能會想用C3P0.

    C3P0是一個隨Hibernate一同分發的開源的JDBC連接池, 它位于lib目錄下。 如果你設置了hibernate.c3p0.*相關的屬性, Hibernate將使用 C3P0ConnectionProvider來緩存JDBC連接. 如果你更原意使用Proxool, 請參考發 行包中的hibernate.properties并到Hibernate網站獲取更多的信息.

    這是一個使用C3P0的hibernate.properties樣例文件:

    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

    為了能在應用程序服務器(application server)中使用Hibernate, 你應當總是將Hibernate 配置成注冊在JNDI中的Datasource處獲得連接,你至少需要設置下列屬性中的一個:

    表 4.2.  Hibernate數據源屬性

    屬性名 用途
    hibernate.connection.datasource 數據源JNDI名字
    hibernate.jndi.url JNDI提供者的URL (可選)
    hibernate.jndi.class JNDI InitialContextFactory (可選)
    hibernate.connection.username 數據庫用戶 (可選)
    hibernate.connection.password 數據庫用戶密碼 (可選)

    這里有一個使用應用程序服務器JNDI數據源的hibernate.properties樣例文件:

    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

    從JNDI數據源獲得的JDBC連接將自動參與應用程序服務器中容器管理的事務(container-managed transactions)中去.

    任何連接(connection)配置屬性的屬性名要以"hibernate.connnection"前綴開頭. 例如, 你可能會使用hibernate.connection.charSet來指定charSet.

    通過實現org.hibernate.connection.ConnectionProvider接口,你可以定義屬于 你自己的獲得JDBC連接的插件策略。通過設置hibernate.connection.provider_class, 你可以選擇一個自定義的實現.

    4.4.  可選的配置屬性

    有大量屬性能用來控制Hibernate在運行期的行為. 它們都是可選的, 并擁有適當的默認值.

    警告: 其中一些屬性是"系統級(system-level)的". 系統級屬性可以通過java -Dproperty=valuehibernate.properties來設置, 而不能用上面描述的其他方法來設置.

    表 4.3.  Hibernate配置屬性

    屬性名 用途
    hibernate.dialect 一個Hibernate Dialect類名允許Hibernate針對特定的關系數據庫生成優化的SQL.

    取值 full.classname.of.Dialect

    hibernate.show_sql 輸出所有SQL語句到控制臺.

    取值 true | false

    hibernate.default_schema 在生成的SQL中, 將給定的schema/tablespace附加于非全限定名的表名上.

    取值 SCHEMA_NAME

    hibernate.default_catalog 在生成的SQL中, 將給定的catalog附加于沒全限定名的表名上.

    取值 CATALOG_NAME

    hibernate.session_factory_name SessionFactory創建后,將自動使用這個名字綁定到JNDI中.

    取值 jndi/composite/name

    hibernate.max_fetch_depth 為單向關聯(一對一, 多對一)的外連接抓取(outer join fetch)樹設置最大深度. 值為0意味著將關閉默認的外連接抓取.

    取值 建議在03之間取值

    hibernate.default_batch_fetch_size 為Hibernate關聯的批量抓取設置默認數量.

    取值 建議的取值為4, 8, 和16

    hibernate.default_entity_mode 為由這個SessionFactory打開的所有Session指定默認的實體表現模式.

    取值 dynamic-map, dom4j, pojo

    hibernate.order_updates 強制Hibernate按照被更新數據的主鍵,為SQL更新排序。這么做將減少在高并發系統中事務的死鎖。

    取值 true | false

    hibernate.generate_statistics 如果開啟, Hibernate將收集有助于性能調節的統計數據.

    取值 true | false

    hibernate.use_identifer_rollback 如果開啟, 在對象被刪除時生成的標識屬性將被重設為默認值.

    取值 true | false

    hibernate.use_sql_comments 如果開啟, Hibernate將在SQL中生成有助于調試的注釋信息, 默認值為false.

    取值 true | false

    表 4.4.  Hibernate JDBC和連接(connection)屬性

    屬性名 用途
    hibernate.jdbc.fetch_size 非零值,指定JDBC抓取數量的大小 (調用Statement.setFetchSize()).
    hibernate.jdbc.batch_size 非零值,允許Hibernate使用JDBC2的批量更新.

    取值 建議取530之間的值

    hibernate.jdbc.batch_versioned_data 如果你想讓你的JDBC驅動從executeBatch()返回正確的行計數 , 那么將此屬性設為true(開啟這個選項通常是安全的). 同時,Hibernate將為自動版本化的數據使用批量DML. 默認值為false.

    eg. true | false

    hibernate.jdbc.factory_class 選擇一個自定義的Batcher. 多數應用程序不需要這個配置屬性.

    eg. classname.of.Batcher

    hibernate.jdbc.use_scrollable_resultset 允許Hibernate使用JDBC2的可滾動結果集. 只有在使用用戶提供的JDBC連接時,這個選項才是必要的, 否則Hibernate會使用連接的元數據.

    取值 true | false

    hibernate.jdbc.use_streams_for_binary 在JDBC讀寫binary (二進制)serializable (可序列化) 的類型時使用流(stream)(系統級屬性).

    取值 true | false

    hibernate.jdbc.use_get_generated_keys 在數據插入數據庫之后,允許使用JDBC3 PreparedStatement.getGeneratedKeys() 來獲取數據庫生成的key(鍵)。需要JDBC3+驅動和JRE1.4+, 如果你的數據庫驅動在使用Hibernate的標 識生成器時遇到問題,請將此值設為false. 默認情況下將使用連接的元數據來判定驅動的能力.

    取值 true|false

    hibernate.connection.provider_class 自定義ConnectionProvider的類名, 此類用來向Hibernate提供JDBC連接.

    取值 classname.of.ConnectionProvider

    hibernate.connection.isolation 設置JDBC事務隔離級別. 查看java.sql.Connection來了解各個值的具體意義, 但請注意多數數據庫都不支持所有的隔離級別.

    取值 1, 2, 4, 8

    hibernate.connection.autocommit 允許被緩存的JDBC連接開啟自動提交(autocommit) (不建議).

    取值 true | false

    hibernate.connection.release_mode 指定Hibernate在何時釋放JDBC連接. 默認情況下,直到Session被顯式關閉或被斷開連接時,才會釋放JDBC連接. 對于應用程序服務器的JTA數據源, 你應當使用after_statement, 這樣在每次JDBC調用后,都會主動的釋放連接. 對于非JTA的連接, 使用after_transaction在每個事務結束時釋放連接是合理的. auto將為JTA和CMT事務策略選擇after_statement, 為JDBC事務策略選擇after_transaction.

    取值 on_close | after_transaction | after_statement | auto

    hibernate.connection.<propertyName> 將JDBC屬性propertyName傳遞到DriverManager.getConnection()中去.
    hibernate.jndi.<propertyName> 將屬性propertyName傳遞到JNDI InitialContextFactory中去.

    表 4.5.  Hibernate緩存屬性

    屬性名 用途
    hibernate.cache.provider_class 自定義的CacheProvider的類名.

    取值 classname.of.CacheProvider

    hibernate.cache.use_minimal_puts 以頻繁的讀操作為代價, 優化二級緩存來最小化寫操作. 在Hibernate3中,這個設置對的集群緩存非常有用, 對集群緩存的實現而言,默認是開啟的.

    取值 true|false

    hibernate.cache.use_query_cache 允許查詢緩存, 個別查詢仍然需要被設置為可緩存的.

    取值 true|false

    hibernate.cache.use_second_level_cache 能用來完全禁止使用二級緩存. 對那些在類的映射定義中指定<cache>的類,會默認開啟二級緩存.

    取值 true|false

    hibernate.cache.query_cache_factory 自定義的實現QueryCache接口的類名, 默認為內建的StandardQueryCache.

    取值 classname.of.QueryCache

    hibernate.cache.region_prefix 二級緩存區域名的前綴.

    取值 prefix

    hibernate.cache.use_structured_entries 強制Hibernate以更人性化的格式將數據存入二級緩存.

    取值 true|false

    表 4.6.  Hibernate事務屬性

    屬性名 用途
    hibernate.transaction.factory_class 一個TransactionFactory的類名, 用于Hibernate Transaction API (默認為JDBCTransactionFactory).

    取值 classname.of.TransactionFactory

    jta.UserTransaction 一個JNDI名字,被JTATransactionFactory用來從應用服務器獲取JTA UserTransaction.

    取值 jndi/composite/name

    hibernate.transaction.manager_lookup_class 一個TransactionManagerLookup的類名 - 當使用JVM級緩存,或在JTA環境中使用hilo生成器的時候需要該類.

    取值 classname.of.TransactionManagerLookup

    hibernate.transaction.flush_before_completion 如果開啟, session在事務完成后將被自動清洗(flush). (在Hibernate和CMT一起使用時很有用.)

    取值 true | false

    hibernate.transaction.auto_close_session 如果開啟, session在事務完成后將被自動關閉. (在Hibernate和CMT一起使用時很有用.)

    取值 true | false

    表 4.7.  其他屬性

    屬性名 用途
    hibernate.query.factory_class 選擇HQL解析器的實現.

    取值 org.hibernate.hql.ast.ASTQueryTranslatorFactory or org.hibernate.hql.classic.ClassicQueryTranslatorFactory

    hibernate.query.substitutions 將Hibernate查詢中的符號映射到SQL查詢中的符號 (符號可能是函數名或常量名字).

    取值 hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC

    hibernate.hbm2ddl.auto SessionFactory創建時,自動將數據庫schema的DDL導出到數據庫. 使用 create-drop時,在顯式關閉SessionFactory時,將drop掉數據庫schema.

    取值 update | create | create-drop

    hibernate.cglib.use_reflection_optimizer 開啟CGLIB來替代運行時反射機制(系統級屬性). 反射機制有時在除錯時比較有用. 注意即使關閉這個優化, Hibernate還是需要CGLIB. 你不能在hibernate.cfg.xml中設置此屬性.

    取值 true | false

    4.4.1.  SQL方言

    你應當總是為你的數據庫屬性hibernate.dialect設置正確的 org.hibernate.dialect.Dialect子類. 如果你指定一種方言, Hibernate將為上面列出的一些屬性使用合理的默認值, 為你省去了手工指定它們的功夫.

    表 4.8.  Hibernate SQL方言 (hibernate.dialect)

    RDBMS 方言
    DB2 org.hibernate.dialect.DB2Dialect
    DB2 AS/400 org.hibernate.dialect.DB2400Dialect
    DB2 OS390 org.hibernate.dialect.DB2390Dialect
    PostgreSQL org.hibernate.dialect.PostgreSQLDialect
    MySQL org.hibernate.dialect.MySQLDialect
    MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect
    MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect
    Oracle (any version) org.hibernate.dialect.OracleDialect
    Oracle 9i/10g org.hibernate.dialect.Oracle9Dialect
    Sybase org.hibernate.dialect.SybaseDialect
    Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
    Microsoft SQL Server org.hibernate.dialect.SQLServerDialect
    SAP DB org.hibernate.dialect.SAPDBDialect
    Informix org.hibernate.dialect.InformixDialect
    HypersonicSQL org.hibernate.dialect.HSQLDialect
    Ingres org.hibernate.dialect.IngresDialect
    Progress org.hibernate.dialect.ProgressDialect
    Mckoi SQL org.hibernate.dialect.MckoiDialect
    Interbase org.hibernate.dialect.InterbaseDialect
    Pointbase org.hibernate.dialect.PointbaseDialect
    FrontBase org.hibernate.dialect.FrontbaseDialect
    Firebird org.hibernate.dialect.FirebirdDialect

    4.4.2.  外連接抓取(Outer Join Fetching)

    如果你的數據庫支持ANSI, Oracle或Sybase風格的外連接, 外連接抓取常能通過限制往返數據庫次數 (更多的工作交由數據庫自己來完成)來提高效率. 外連接允許在單個SELECTSQL語句中, 通過many-to-one, one-to-many, many-to-many和one-to-one關聯獲取連接對象的整個對象圖.

    hibernate.max_fetch_depth設為0能在全局 范圍內禁止外連接抓取. 設為1或更高值能啟用one-to-one和many-to-oneouter關聯的外連接抓取, 它們通過 fetch="join"來映射.

    參見第 20.1 節 “ 抓取策略(Fetching strategies) ”獲得更多信息.

    4.4.3.  二進制流 (Binary Streams)

    Oracle限制那些通過JDBC驅動傳輸的字節數組的數目. 如果你希望使用二進值 (binary)可序列化的 (serializable)類型的大對象, 你應該開啟 hibernate.jdbc.use_streams_for_binary屬性. 這是系統級屬性.

    4.4.4.  二級緩存與查詢緩存

    hibernate.cache為前綴的屬性允許你在Hibernate中,使用進程或群集范圍內的二級緩存系統. 參見第 20.2 節 “二級緩存(The Second Level Cache) ”獲取更多的詳情.

    4.4.5.  查詢語言中的替換

    你可以使用hibernate.query.substitutions在Hibernate中定義新的查詢符號. 例如:

    hibernate.query.substitutions true=1, false=0

    將導致符號truefalse在生成的SQL中被翻譯成整數常量.

    hibernate.query.substitutions toLowercase=LOWER

    將允許你重命名SQL中的LOWER函數.

    4.4.6.  Hibernate的統計(statistics)機制

    如果你開啟hibernate.generate_statistics, 那么當你通過 SessionFactory.getStatistics()調整正在運行的系統時,Hibernate將導出大量有用的數據. Hibernate甚至能被配置成通過JMX導出這些統計信息. 參考org.hibernate.stats中接口的Javadoc,以獲得更多信息.

    4.5.  日志

    Hibernate使用Apache commons-logging來為各種事件記錄日志.

    commons-logging將直接輸出到Apache Log4j(如果在類路徑中包括log4j.jar)或 JDK1.4 logging (如果運行在JDK1.4或以上的環境下). 你可以從http://jakarta.apache.org 下載Log4j. 要使用Log4j,你需要將log4j.properties文件放置在類路徑下, 隨Hibernate 一同分發的樣例屬性文件在src/目錄下.

    我們強烈建議你熟悉一下Hibernate的日志消息. 在不失可讀性的前提下, 我們做了很多工作,使Hibernate的日志可能地詳細. 這是必要的查錯利器. 最令人感興趣的日志分類有如下這些:

    表 4.9.  Hibernate日志類別

    類別 功能
    org.hibernate.SQL 在所有SQL DML語句被執行時為它們記錄日志
    org.hibernate.type 為所有JDBC參數記錄日志
    org.hibernate.tool.hbm2ddl 在所有SQL DDL語句執行時為它們記錄日志
    org.hibernate.pretty 在session清洗(flush)時,為所有與其關聯的實體(最多20個)的狀態記錄日志
    org.hibernate.cache 為所有二級緩存的活動記錄日志
    org.hibernate.transaction 為事務相關的活動記錄日志
    org.hibernate.jdbc 為所有JDBC資源的獲取記錄日志
    org.hibernate.hql.ast 為HQL和SQL的自動狀態轉換和其他關于查詢解析的信息記錄日志
    org.hibernate.secure 為JAAS認證請求做日志
    org.hibernate 為任何Hibernate相關信息做日志 (信息量較大, 但對查錯非常有幫助)

    在使用Hibernate開發應用程序時, 你應當總是為org.hibernate.SQL 開啟debug級別的日志記錄,或者開啟hibernate.show_sql屬性來代替它。.

    4.6.  實現NamingStrategy

    org.hibernate.cfg.NamingStrategy接口允許你為數據庫中的對象和schema 元素指定一個“命名標準”.

    你可能會提供一些通過Java標識生成數據庫標識或將映射定義文件中"邏輯"表/列名處理成"物理"表/列名的規則. 這個特性有助于減少冗長的映射定義文件.

    在加入映射定義前,你可以調用 Configuration.setNamingStrategy()指定一個不同的命名策略:

    SessionFactory sf = new Configuration()
    .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
    .addFile("Item.hbm.xml")
    .addFile("Bid.hbm.xml")
    .buildSessionFactory();

    org.hibernate.cfg.ImprovedNamingStrategy是一個內建的命名策略, 對 一些應用程序而言,可能是非常有用的起點.

    4.7.  XML配置文件

    另一個配置方法是在hibernate.cfg.xml文件中指定一套完整的配置. 這個文件可以當成hibernate.properties的替代。 若兩個文件同時存在,它將重載前者的屬性.

    XML配置文件被默認是放在CLASSPATH的根目錄下. 這是一個例子:

     

    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
    <!-- 以/jndi/name綁定到JNDI的SessionFactory實例 -->
    <session-factory
    name="java:hibernate/SessionFactory">
    <!-- 屬性 -->
    <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="show_sql">false</property>
    <property name="transaction.factory_class">
    org.hibernate.transaction.JTATransactionFactory
    </property>
    <property name="jta.UserTransaction">java:comp/UserTransaction</property>
    <!-- 映射定義文件 -->
    <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
    <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
    <!-- 緩存設置 -->
    <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
    <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
    <collection-cache class="org.hibernate.auction.Item.bids" usage="read-write"/>
    </session-factory>
    </hibernate-configuration>

    如你所見, 這個方法優勢在于,在配置文件中指出了映射定義文件的名字. 一旦你需要調整Hibernate的緩存, hibernate.cfg.xml也是更方便. 注意,使用hibernate.properties還是 hibernate.cfg.xml完全是由你來決定, 除了上面提到的XML語法的優勢之外, 兩者是等價的.

    使用XML配置,使得啟動Hibernate變的異常簡單, 如下所示,一行代碼就可以搞定:

    SessionFactory sf = new Configuration().configure().buildSessionFactory();

    你可以使用如下代碼來添加一個不同的XML配置文件

    SessionFactory sf = new Configuration()
    .configure("catdb.cfg.xml")
    .buildSessionFactory();

    4.8.  J2EE應用程序服務器的集成

    針對J2EE體系,Hibernate有如下幾個集成的方面:

    • 容器管理的數據源(Container-managed datasources): Hibernate能通過容器管理由JNDI提供的JDBC連接. 通常, 特別是當處理多個數據源的分布式事務的時候, 由一個JTA兼容的TransactionManager和一個 ResourceManager來處理事務管理(CMT, 容器管理的事務). 當然你可以通過 編程方式來劃分事務邊界(BMT, Bean管理的事務). 或者為了代碼的可移植性,你也也許會想使用可選的 Hibernate Transaction API.

    • 自動JNDI綁定: Hibernate可以在啟動后將 SessionFactory綁定到JNDI.

    • JTA Session綁定: 如果使用EJB, Hibernate Session 可以自動綁定到JTA事務作用的范圍. 只需簡單地從JNDI查找SessionFactory并獲得當前的 Session. 當JTA事務完成時, 讓Hibernate來處理 Session的清洗(flush)與關閉. 在EJB的部署描述符中事務邊界是聲明式的.

    • JMX部署: 如果你使用支持JMX應用程序服務器(如, JBoss AS), 那么你可以選擇將Hibernate部署成托管MBean. 這將為你省去一行從Configuration構建SessionFactory的啟動代碼. 容器將啟動你的HibernateService, 并完美地處理好服務間的依賴關系 (在Hibernate啟動前,數據源必須是可用的等等).

    如果應用程序服務器拋出"connection containment"異常, 根據你的環境,也許該將配置屬性 hibernate.connection.release_mode設為after_statement.

    4.8.1.  事務策略配置

    在你的架構中,Hibernate的Session API是獨立于任何事務分界系統的. 如果你讓Hibernate通過連接池直接使用JDBC, 你需要調用JDBC API來打開和關閉你的事務. 如果你運行在J2EE應用程序服務器中, 你也許想用Bean管理的事務并在需要的時候調用JTA API和UserTransaction.

    為了讓你的代碼在兩種(或其他)環境中可以移植,我們建議使用可選的Hibernate Transaction API, 它包裝并隱藏了底層系統. 你必須通過設置Hibernate配置屬性hibernate.transaction.factory_class來指定 一個Transaction實例的工廠類.

    存在著三個標準(內建)的選擇:

    org.hibernate.transaction.JDBCTransactionFactory

    委托給數據庫(JDBC)事務(默認)

    org.hibernate.transaction.JTATransactionFactory

    如果在上下文環境中存在運行著的事務(如, EJB會話Bean的方法), 則委托給容器管 理的事務, 否則,將啟動一個新的事務,并使用Bean管理的事務.

    org.hibernate.transaction.CMTTransactionFactory

    委托給容器管理的JTA事務

    你也可以定義屬于你自己的事務策略 (如, 針對CORBA的事務服務)

    Hibernate的一些特性 (即二級緩存, JTA與Session的自動綁定等等)需要訪問在托管環境中的JTA TransactionManager. 由于J2EE沒有標準化一個單一的機制,Hibernate在應用程序服務器中,你必須指定Hibernate如何獲得TransactionManager的引用:

    表 4.10. JTA TransactionManagers

    Transaction工廠類 應用程序服務器
    org.hibernate.transaction.JBossTransactionManagerLookup JBoss
    org.hibernate.transaction.WeblogicTransactionManagerLookup Weblogic
    org.hibernate.transaction.WebSphereTransactionManagerLookup WebSphere
    org.hibernate.transaction.WebSphereExtendedJTATransactionLookup WebSphere 6
    org.hibernate.transaction.OrionTransactionManagerLookup Orion
    org.hibernate.transaction.ResinTransactionManagerLookup Resin
    org.hibernate.transaction.JOTMTransactionManagerLookup JOTM
    org.hibernate.transaction.JOnASTransactionManagerLookup JOnAS
    org.hibernate.transaction.JRun4TransactionManagerLookup JRun4
    org.hibernate.transaction.BESTransactionManagerLookup Borland ES

    4.8.2.  JNDI綁定的SessionFactory

    與JNDI綁定的Hibernate的SessionFactory能簡化工廠的查詢,簡化創建新的Session. 需要注意的是這與JNDI綁定Datasource沒有關系, 它們只是恰巧用了相同的注冊表!

    如果你希望將SessionFactory綁定到一個JNDI的名字空間, 用屬性hibernate.session_factory_name指定一個名字(如, java:hibernate/SessionFactory). 如果不設置這個屬性, SessionFactory將不會被綁定到JNDI中. (在以只讀JNDI為默認實現的環境中,這個設置尤其有用, 如Tomcat.)

    在將SessionFactory綁定至JNDI時, Hibernate將使用hibernate.jndi.url, 和hibernate.jndi.class的值來實例化初始環境(initial context). 如果它們沒有被指定, 將使用默認的InitialContext.

    在你調用cfg.buildSessionFactory()后, Hibernate會自動將SessionFactory注冊到JNDI. 這意味這你至少需要在你應用程序的啟動代碼(或工具類)中完成這個調用, 除非你使用HibernateService來做JMX部署 (見后面討論).

    如果你使用與JNDI綁定的SessionFactory, EJB或任何其他類可以通過一個JNDI查詢來獲得這個SessionFactory. 請注意, 如果你使用第一章中介紹的幫助類HibernateUtil - 類似Singleton(單實例)注冊表, 那么這里的啟動代碼不是必要的. 但HibernateUtil更多被使用在非托管環境中.

    4.8.3.  JTA和Session的自動綁定

    在非托管環境中,我們建議:HibernateUtil和靜態SessionFactory一起工作, 由ThreadLocal管理Hibernate Session。 由于一些EJB可能會運行在同一個事務但不同線程的環境中, 所以這個方法不能照搬到EJB環境中. 我們建議在托管環境中,將SessionFactory綁定到JNDI上.

    請使用SessionFactorygetCurrentSession()方法來代替 直接使用ThreadLocal去獲得Hibernate Session. 如果在當前JTA事務中沒有Hibernate Session, 將會啟動一個并將它關聯到事務中. 對于使用getCurrentSession()獲得的每個Session而言, hibernate.transaction.flush_before_completionhibernate.transaction.auto_close_session這兩個配置選項會自動設置, 因此在容器結束JTA事務時,這些Session會被自動清洗(flush)并關閉.

    例如,如果你使用DAO模式來編寫你的持久層, 那么在需要時,所有DAO將查找SessionFactory并打開"當前"Session. 沒有必要在控制代碼和DAO代碼間傳遞SessionFactorySession的實例.

    4.8.4.  JMX部署

    為了將SessionFactory注冊到JNDI中cfg.buildSessionFactory()這行代碼仍需在某處被執行. 你可在一個static初始化塊(像HibernateUtil中的那樣)中執行它或將Hibernate部署為一個托管的服務.

    為了部署在一個支持JMX的應用程序服務器上,Hibernate和 org.hibernate.jmx.HibernateService一同分發,如Jboss AS。 實際的部署和配置是由應用程序服務器提供者指定的. 這里是JBoss 4.0.x的jboss-service.xml樣例:

    <?xml version="1.0"?>
    <server>
    <mbean code="org.hibernate.jmx.HibernateService"
    name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
    <!-- 必須的服務 -->
    <depends>jboss.jca:service=RARDeployer</depends>
    <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
    <!-- 將Hibernate服務綁定到JNDI -->
    <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>
    <!-- 數據源設置 -->
    <attribute name="Datasource">java:HsqlDS</attribute>
    <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
    <!-- 事務集成 -->
    <attribute name="TransactionStrategy">
    org.hibernate.transaction.JTATransactionFactory</attribute>
    <attribute name="TransactionManagerLookupStrategy">
    org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
    <attribute name="FlushBeforeCompletionEnabled">true</attribute>
    <attribute name="AutoCloseSessionEnabled">true</attribute>
    <!-- 抓取選項 -->
    <attribute name="MaximumFetchDepth">5</attribute>
    <!-- 二級緩存 -->
    <attribute name="SecondLevelCacheEnabled">true</attribute>
    <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
    <attribute name="QueryCacheEnabled">true</attribute>
    <!-- 日志 -->
    <attribute name="ShowSqlEnabled">true</attribute>
    <!-- 映射定義文件 -->
    <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
    </mbean>
    </server>

    這個文件是部署在META-INF目錄下的, 并會被打包到以.sar (service archive)為擴展名的JAR文件中. 同時,你需要打包Hibernate, 它所需要的第三方庫, 你編譯好的持久化類及你的映射定義文件打包進同一個文檔. 你的企業Bean(一般為會話Bean)可能會被打包成它們自己的JAR文件, 但你也許會將EJB JAR文件一同包含進能獨立(熱)部署的主服務文檔. 咨詢JBoss AS文檔以了解更多的JMX服務與EJB部署的信息.

    posted on 2007-04-03 09:52 ???MengChuChen 閱讀(1588) 評論(0)  編輯  收藏 所屬分類: hibernate
    主站蜘蛛池模板: 亚洲视频免费播放| 又大又硬又爽免费视频| 久久国产亚洲精品麻豆| 国产黄片不卡免费| 国产gv天堂亚洲国产gv刚刚碰 | 亚洲一区二区视频在线观看| 亚洲AV色无码乱码在线观看| 在线a人片天堂免费观看高清| 亚洲色精品三区二区一区| 免费观看男人免费桶女人视频| 亚洲精品无码久久久久A片苍井空| 德国女人一级毛片免费 | 日韩精品免费一线在线观看| 一区二区三区亚洲视频| WWW国产成人免费观看视频| 亚洲精品无码久久千人斩| 精品国产免费一区二区三区香蕉 | 亚洲国产亚洲片在线观看播放 | 香蕉蕉亚亚洲aav综合| 最近免费视频中文字幕大全| 亚洲日本在线免费观看| 国内一级一级毛片a免费| 亚洲AV日韩AV无码污污网站| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 久久亚洲精品中文字幕无码| jjizz全部免费看片| 亚洲精品国产av成拍色拍| 亚洲精品成人区在线观看| 久久99精品免费视频| 亚洲三级高清免费| 亚洲国产精品人人做人人爱| 久久午夜夜伦鲁鲁片免费无码 | 日本亚洲国产一区二区三区| 一区二区在线免费观看| 亚洲午夜精品一区二区麻豆| 自拍偷自拍亚洲精品被多人伦好爽 | 成熟女人特级毛片www免费| 日韩色视频一区二区三区亚洲 | 亚洲一区二区三区久久久久| 亚洲国产精品国产自在在线 | 免费日韩在线视频|