作者 Stefan Tilkov譯者 苑永凱 發布于 2007年12月25日 下午10時10分
不知你是否意識到,圍繞著什么才是實現異構的應用到應用通信的“正確”方式,一場爭論正進行的如火如荼:雖然當前主流的方式明顯地集中在基于 SOAP、WSDL和WS-*規范的Web Services領域,但也有少數人用細小但洪亮的聲音主張說更好的方式是REST,表述性狀態轉移(REpresentational State Transfer)的簡稱。在本文中,我不會涉及爭論的話題,而是嘗試對REST和RESTful HTTP應用集成做實用性的介紹。以我的經驗,有些話題一旦觸及就會引來眾多的討論,當涉及到這方面話題的時候,我會深入詳細地闡述。
大部分對REST的介紹是以其正式的定義和背景作為開場的。但這兒且先按下不表,我先提出一個簡單扼要的定義:REST定義了應該如何正確地使用 (這和大多數人的實際使用方式有很大不同)Web標準,例如HTTP和URI。如果你在設計應用程序時能堅持REST原則,那就預示著你將會得到一個使用 了優質Web架構(這將讓你受益)的系統。總之,五條關鍵原則列舉如下:
下面讓我們進一步審視這些原則。
在這里我使用了“事物”來代替更正式準確的術語“資源”,因為一條如此簡單的原則,不應該被淹沒在術語當中。思考一下人們構建的系統,通常會找到一 系列值得被標識的關鍵抽象。每個事物都應該是可標識的,都應該擁有一個明顯的ID——在Web中,代表ID的統一概念是:URI。URI構成了一個全局命 名空間,使用URI標識你的關鍵資源意味著它們獲得了一個唯一、全局的ID。
對事物使用一致的命名規則(naming scheme)最主要的好處就是你不需要提出自己的規則——而是依靠某個已被定義,在全球范圍中幾乎完美運行,并且能被絕大多數人所理解的規則。想一下你 構建的上一個應用(假設它不是采用RESTful方式構建的)中的任意一個高級對象(high-level object),那就很有可能看到許多從使用唯一標識中受益的用例。比如,如果你的應用中包含一個對顧客的抽象,那么我可以相當肯定,用戶會希望將一個指 向某個顧客的鏈接,能通過電子郵件發送到同事那里,或者加入到瀏覽器的書簽中,甚至寫到紙上。更透徹地講:如果在一個類似于Amazon.com的在線商 城中,沒有用唯一的ID(一個URI)標識它的每一件商品,可想而知這將是多么可怕的業務決策。
當面對這個原則時,許多人驚訝于這是否意味著需要直接向外界暴露數據庫記錄(或者數據庫記錄ID)——自從多年以來面向對象的實踐告誡我們,要將持 久化的信息作為實現細節隱藏起來之后,哪怕是剛有點想法都常會使人驚恐。但是這條原則與隱藏實現細節兩者之間并沒有任何沖突:通常,值得被URI標識的事 物——資源——要比數據庫記錄抽象的多。例如,一個定單資源可以由定單項、地址以及許多其它方面(可能不希望作為單獨標識的資源暴露出來)組成。標識所有 值得標識的事物,領會這個觀念可以進一步引導你創造出在傳統的應用程序設計中不常見的資源:一個流程或者流程步驟、一次銷售、一次談判、一份報價請求—— 這都是應該被標識的事物的示例。同樣,這也會導致創建比非RESTful設計更多的持久化實體。
下面是一些你可能想到的URI的例子:
http://example.com/customers/1234
http://example.com/orders/2007/10/776654
http://example.com/products/4554
http://example.com/processes/salary-increase-234
正如我選擇了創建便于閱讀的URI——這是個有用的觀點,盡管不是RESTful設計所必須的——應該能十分容易地推測出URI的含義:它們明顯地標識著單一“數據項”。但是再往下看:
http://example.com/orders/2007/11
http://example.com/products?color=green
首先,這兩個URI看起來與之前的稍有不同——畢竟,它們不是對一件事物的標識,而是對一類事物集合的標識(假定第一個URI標識了所有在2007年11月份提交的定單,第二個則是綠顏色產品的集合)。但是這些集合自身也是事物(資源),也應該被標識。
注意,使用唯一、全局統一的命名規則的好處,既適用于瀏覽器中的Web應用,也適用于機對機(machine-to-machine,m2m)通信。
來對第一個原則做下總結:使用URI標識所有值得標識的事物,特別是應用中提供的所有“高級”資源,無論這些資源代表單一數據項、數據項集合、虛擬亦或實際的對象還是計算結果等。
接下來要討論的原則有一個有點令人害怕的正式描述:“超媒體被當作應用狀態引擎(Hypermedia as the engine of application state)”,有時簡寫為HATEOAS。(嚴格地說,這不是我說的。)這個描述的核心是超媒體概念,換句話說:是鏈接的思想。鏈接是我們在HTML中常見的概念,但是它的用處絕不局限于此(用于人們網絡瀏覽)。考慮一下下面這個虛構的XML片段:
如果你觀察文檔中product和customer的鏈接,就可以很容易地想象到,應用程序(已經檢索過文檔)如何“跟隨”鏈接檢索更多的信息。當然,如果使用一個遵守專用命名規范的簡單“id”屬性作為鏈接, 也是可行的——但是僅限于應用環境之內。使用URI表示鏈接的優雅之處在于,鏈接可以指向由不同應用、不同服務器甚至位于另一個大陸上的不同公司提供的資源——因為URI命名規范是全球標準,構成Web的所有資源都可以互聯互通。<order self="http://example.com/customers/1234">
<amount>23</amount>
<product ref="http://example.com/products/4554">
<customer ref="http://example.com/customers/1234">
</customer>
</product>
</order>
超媒體原則還有一個更重要的方面——應用“狀態”。簡而言之,實際上服務器端(如果你愿意,也可以叫服務提供者)為客戶端(服務消費者)提供一組鏈 接,使客戶端能通過鏈接將應用從一個狀態改變為另一個狀態。稍后我們會在另一篇文章中探究這個方面的影響;目前,只需要記住:鏈接是構成動態應用的非常有 效的方式。
對此原則總結如下:任何可能的情況下,使用鏈接指引可以被標識的事物(資源)。也正是超鏈接造就了現在的Web。
在前兩個原則的討論中暗含著一個假設:接收URI的應用程序可以通過URI明確地做一些有意義的事情。如果你在公共汽車上看到一個URI,你可以將它輸入瀏覽器的地址欄中并回車——但是你的瀏覽器如何知道需要對這個URI做些什么呢?
它知道如何去處理URI的原因在于所有的資源都支持同樣的接口,一套同樣的方法(只要你樂意,也可以稱為操作)集合。在HTTP中這被叫做動詞 (verb),除了兩個大家熟知的(GET和POST)之外,標準方法集合中還包含PUT、DELETE、HEAD和OPTIONS。這些方法的含義連同 行為許諾都一起定義在HTTP規范之中。如果你是一名OO開發人員,就可以想象到RESTful HTTP方案中的所有資源都繼承自類似于這樣的一個類(采用類Java、C#的偽語法描述,請注意關鍵的方法):
class Resource {
Resource(URI u);
Response get();
Response post(Request r);
Response put(Request r);
Response delete();
}
由于所有資源使用了同樣的接口,你可以依此使用GET方法檢索一個表述(representation)——也 就是對資源的描述。因為規范中定義了GET的語義,所以可以肯定當你調用它的時候不需要對后果負責——這就是為什么可以“安全”地調用此方法。GET方法 支持非常高效、成熟的緩存,所以在很多情況下,你甚至不需要向服務器發送請求。還可以肯定的是,GET方法具有冪等性[譯 注:指多個相同請求返回相同的結果]——如果你發送了一個GET請求沒有得到結果,你可能不知道原因是請求未能到達目的地,還是響應在反饋的途中丟失了。 冪等性保證了你可以簡單地再發送一次請求解決問題。冪等性同樣適用于PUT(基本的含義是“更新資源數據,如果資源不存在的話,則根據此URI創建一個新 的資源”)和DELETE(你完全可以一遍又一遍地操作它,直到得出結論——刪除不存在的東西沒有任何問題)方法。POST方法,通常表示“創建一個新資 源”,也能被用于調用任意過程,因而它既不安全也不具有冪等性。
如果你采用RESTful的方式暴露應用功能(如果你樂意,也可以稱為服務功能),那這條原則和它的約束同樣也適用于你。如果你已經習慣于另外的設計方式,則很難去接受這條原則——畢竟,你很可能認為你的應用包含了超出這些操作表達范圍的邏輯。請允許我花費一些時間來讓你相信不存在這樣的情況。
來看下面這個簡單的采購方案例子:
可以看到,例子中定義了兩個服務程序(沒有包含任何實現細節)。這些服務程序的接口都是為了完成任務(正是我們討論的 OrderManagement和CustomerManagement服務)而定制的。如果客戶端程序試圖使用這些服務,那它必須針對這些特定接口進行 編碼——不可能在這些接口定義之前,使用客戶程序去有目的地和接口協作。這些接口定義了服務程序的應用協議(application protocol)。
在RESTful HTTP方式中,你將通過組成HTTP應用協議的通用接口訪問服務程序。你可能會想出像這樣的方式:
可以看到,服務程序中的特定操作被映射成為標準的HTTP方法——為了消除歧義,我創建了一組全新的資源。“這是騙人的把戲”,我聽見你叫嚷著。 不,這不是欺騙。標識一個顧客的URI上的GET方法正好相當于getCustomerDetails操作。有人用三角形形象化地說明了這一點:
把三個頂點想象為你可以調節的按鈕。可以看到在第一種方法中,你擁有許多操作,許多種類的數據以及固定數量的“實例”(本質上和你擁有的服務程序數 量一致)。在第二種方法中,你擁有固定數量的操作,許多種類的數據和許多調用固定方法的對象。它的意義在于,證明了通過這兩種方式,你基本上可以表示任何 你喜歡的事情。
為什么使用標準方法如此重要?從根本上說,它使你的應用成為Web的一部分——應用程序為Web變成Internet上最成功的應用所做的貢獻,與 它添加到Web中的資源數量成比例。采用RESTful方式,一個應用可能會向Web中添加數以百萬計的客戶URI;如果采用CORBA技術并維持應用的 原有設計方式,那它的貢獻大抵只是一個“端點(endpoint)”——就好比一個非常小的門,僅僅允許有鑰匙的人進入其中的資源域。
統一接口也使得所有理解HTTP應用協議的組件能與你的應用交互。通用客戶程序(generic client)就是從中受益的組件的例子,例如curl、wget、代理、緩存、HTTP服務器、網關還有Google、Yahoo!、MSN等等。
總結如下:為使客戶端程序能與你的資源相互協作,資源應該正確地實現默認的應用協議(HTTP),也就是使用標準的GET、PUT、POST和DELETE方法。
到目前為止我們一直忽略了一個稍微復雜的問題:客戶程序如何知道該怎樣處理檢索到的數據,比如作為GET或者POST請求的結果?原因是,HTTP 采取的方式是允許數據處理和操作調用之間關系分離的。換句話說,如果客戶程序知道如何處理一種特定的數據格式,那就可以與所有提供這種表述格式的資源交 互。讓我們再用一個例子來闡明這個觀點。利用HTTP內容協商(content negotiation),客戶程序可以請求一種特定格式的表述:
GET /customers/1234 HTTP/1.1
Host: example.com
Accept: application/vnd.mycompany.customer+xml
請求的結果可能是一些由公司專有的XML格式表述的客戶信息。假設客戶程序發送另外一個不同的請求,就如下面這樣:
GET /customers/1234 HTTP/1.1
Host: example.com
Accept: text/x-vcard
結果則可能是VCard格式的客戶地址。(在這里我沒有展示響應的內容,在其HTTP Content-type頭中應該包含著關于數據類型的元數據。)這說明為什么理想的情況下,資源表述應該采用標準格式——如果客戶程序對HTTP應用協 議和一組數據格式都有所“了解”,那么它就可以用一種有意義的方式與世界上任意一個RESTful HTTP應用交互。 不幸的是,我們不可能拿到所有東西的標準格式,但是,或許我們可以想到在公司或者一些合作伙伴中使用標準格式來營造一個小環境。當然以上情況不僅適用于從 服務器端到客戶端的數據,反之既然——倘若從客戶端傳來的數據符合應用協議,那么服務器端就可以使用特定的格式處理數據,而不去關心客戶端的類型。
在實踐中,資源多重表述還有著其它重要的好處:如果你為你的資源提供HTML和XML兩種表述方式,那這些資源不僅可以被你的應用所用,還可以被任意標準Web瀏覽器所用——也就是說,你的應用信息可以被所有會使用Web的人獲取到。
資源多重表述還有另外一種使用方式:你可以將應用的Web UI納入到Web API中——畢竟,API的設計通常是由UI可以提供的功能驅動的,而UI也是通過API執行動作的。將這兩個任務合二為一帶來了令人驚訝的好處,這使得 使用者和調用程序都能得到更好的Web接口。
總結:針對不同的需求提供資源多重表述。
無狀態通信是我要講到的最后一個原則。首先,需要著重強調的是,雖然REST包含無狀態性(statelessness)的觀念,但這并不是說暴露功能的應用不能有狀態——
事實上,在大部分情況下這會導致整個做法沒有任何用處。REST要求狀態要么被放入資源狀態中,要么保存在客戶端上。或者換句話說,服務器端不能保持除了
單次請求之外的,任何與其通信的客戶端的通信狀態。這樣做的最直接的理由就是可伸縮性——
如果服務器需要保持客戶端狀態,那么大量的客戶端交互會嚴重影響服務器的內存可用空間(footprint)。(注意,要做到無狀態通信往往需要需要一些
重新設計——不能簡單地將一些session狀態綁縛在URI上,然后就宣稱這個應用是RESTful。)
但除此以外,其它方面可能顯得更為重要:無狀態約束使服務器的變化對客戶端是不可見的,因為在兩次連續的請求中,客戶端并不依賴于同一臺服務器。一 個客戶端從某臺服務器上收到一份包含鏈接的文檔,當它要做一些處理時,這臺服務器宕掉了,可能是硬盤壞掉而被拿去修理,可能是軟件需要升級重啟——如果這 個客戶端訪問了從這臺服務器接收的鏈接,它不會察覺到后臺的服務器已經改變了。
我承認:以上我所說的REST不是真正的REST,而且我可能有點過多地熱衷于簡單化。但因為我想有一個與眾不同的開場,所以沒有在一開始就介紹其正式的定義和背景。現在就讓我們稍微簡要地介紹一下這方面的內容。
首先,先前我并沒有明確地區分HTTP、RESTful HTTP和REST。要理解這些不同方面之間的關系,我們要先來看看REST的歷史。
Roy T. Fielding在他的博士學位論文(實際上你應該訪問這個鏈接——至少對于一篇學術論文來說,它是相當易讀的。此論文已被翻譯成中文) 中定義了術語REST。Roy曾是許多基本Web協議的主要設計者,其中包括HTTP和URIs,并且他在論文中對這些協議提出了很多想法。(這篇論文被 譽為“REST圣經”,這是恰當的——畢竟,是作者發明了這個術語,所以在定義上,他寫的任何內容都被認為是權威的。)在論文中,Roy首先定義一種方法 論來談論架構風格——高級、抽象的模式,來表達架構方法背后的核心理念。每一個架構風格由一系列的約束(constraints)定義形成。架構風格的例子包括“沒有風格”(根本沒有任何約束)、管道和過濾器(pipe and filter)、客戶端/服務器、分布式對象以及——你猜到它了——REST。
如果對你來說這些聽起來都太抽象了,那就對了——REST在本質上是一個可以被許多不同技術實現的高層次的風格,而且可以被實例化——通過為它的抽 象特性賦上不同的值。比如,REST中包含資源和統一接口的概念——也就是說,所有資源都應該對這些相同的方法作出反應。但是REST并沒有說明是哪些方 法,或者有多少方法。
REST風格的一個“化身”便是HTTP(以及一套相關的一套標準,比如URI),或者稍微抽象一些:Web架構自身。接著上面的例子,HTTP使 用HTTP動詞作為REST統一接口的“實例”。由于Fielding是在Web已經(或者至少是大部分)“完善”了之后才定義的REST風格,有人可能 會爭論兩者是不是100%的匹配。但是無論如何,整體上來說Web、HTTP和URI僅僅是REST風格的一個主要實現。不過,由于Roy Fielding即是REST論文的作者,又對Web架構設計有過深遠的影響,兩者相似也在情理之中。
最后,我在前面一次又一次地使用著術語“RESTful HTTP”,原因很簡單:許多使用HTTP的應用因為一些理由并沒有遵循REST原則,有人會說使用HTTP而不遵循REST原則就等同于濫用HTTP。 當然這聽起來有點狂熱——事實上違反REST約束的原因通常是,僅僅因為每個約束帶來的設計權衡可能不適合于一些特殊情況。但通常,違背REST約束的原 因可歸咎于對其好處認知的缺乏。來看一個明顯的反面案例:使用HTTP GET調用類似于刪除對象的操作,這違反了REST的安全約束和一般性常識(客戶程序不應為此負責,服務器端開發人員大概不是有意而為之)。但在隨后的文 章中,我會提及更多這樣或那樣的對HTTP的濫用。
本文試圖對REST(Web架構)背后的概念提供快速的介紹。RESTful HTTP暴露功能的方式與RPC、分布式對象以及Web Services是不相同的;要真正理解這些不同是需要一些心態的轉變。不管你構建的應用是僅僅想暴露Web UI還是想把API變成Web的一份子,了解下REST的原則還是有好處的。
Stefan Tilkov是InfoQ SOA社區的首席編輯,并且是位于德國和瑞士的innoQ公司的共同創始人、首席顧問和REST狂熱分子首領。
查看英文原文:A Brief Introduction to REST表 3.4. Hibernate JDBC和連接(connection)屬性
屬性名 | 用途 |
---|---|
hibernate.jdbc.fetch_size | 非零值,指定JDBC抓取數量的大小 (調用Statement.setFetchSize()). |
hibernate.jdbc.batch_size | 非零值,允許Hibernate使用JDBC2的批量更新. 取值 建議取5到30之間的值 |
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中去. |
表 3.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 |
表 3.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)。 現在更好的方法是使用自動session上下文管理。取值 true | false |
hibernate.transaction.auto_close_session | 如果開啟, session在事務完成后將被自動關閉。 現在更好的方法是使用自動session上下文管理。取值 true | false |
表 3.7. 其他屬性
屬性名 | 用途 |
---|---|
hibernate.current_session_context_class | 為"當前" Session指定一個(自定義的)策略。eg. jta | thread | custom.Class |
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. 取值 validate | update | create | create-drop |
hibernate.cglib.use_reflection_optimizer | 開啟CGLIB來替代運行時反射機制(系統級屬性). 反射機制有時在除錯時比較有用. 注意即使關閉這個優化, Hibernate還是需要CGLIB. 你不能在hibernate.cfg.xml中設置此屬性. 取值 true | false |
你應當總是為你的數據庫將hibernate.dialect屬性設置成正確的 org.hibernate.dialect.Dialect子類. 如果你指定一種方言, Hibernate將為上面列出的一些屬性使用合理的默認值, 為你省去了手工指定它們的功夫.
表 3.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 |
表 3.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的AST分析日志 |
org.hibernate.secure | 為JAAS認證請求做日志 |
org.hibernate | 為任何Hibernate相關信息做日志 (信息量較大, 但對查錯非常有幫助) |
表 3.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 |
網管下載dl.bitscn.com