Hibernate中配置主要分為兩種:
一種包含了Hibernate與數據庫的基本連接信息,在Hibernate工作的初始階段,這些信息被先后加載到Configuration和SessionFactory實例;
另一種包含了Hibernate的基本映射信息,即系統中每一個類與其對應的數據庫表之間的關聯信息,在Hibernate工作的初始階段,這些信息通過hibernate.cfg.xml的mapping節點被加載到Configuration和SessionFactory實例。這兩種文件信息包含了Hibernate的所有運行期參數。
下面我們用詳細的例子來說明這兩種文件的基本結構和內容。
實現包含了Hibernate與數據庫的基本連接信息的配置方式有兩種方式:
<li>使用hibernate.properties文件作為配置文件。
<li>使用hibernate.cfg.xml文件作為配置文件。
- 使用hibernateproperties作為配置文件
對于hibernate.properties作為配置文件的方式,比較適合于初學者。因為初學者往往很難記住xml配置文件的格式,以及需要配置哪些屬性。
在Hibernate發布包的etc路徑下,提供了一個hibernate.properties文件,該文件列出了Hibernate 的所有屬性。每個配置段都給出了大致的注釋,用戶只要取消所需配置段的注釋,就可以快速配置Hibernate和數據庫的鏈接此處給出使用hibernate.properties文件創建Configuration對象的方法。
//實例化configuration對象
Configuration cfg = new Configuration()
//多次調用addResource()方法,添加映射文件
cfg.addResource("Item.hbm.xml")
cfg.addResource("Bid.hbm.xml");
查看hibernate.properties文件發現,該文件沒有提供Hibernate映射文件的方式。因此使用hibernate.properties文件來作為配置文件時,必須使用Configuration的.addResource()方法,使用該方法來添加映射文件。
注意:正如上面的代碼所示,使用hibernate.properties文件配置Hibernate的屬性固然簡單,但是因為要手動添加映射文件,當映射文件極其多時,這是一件非常催人淚下的事情。這也就是在實際開發中,不常使用hibernate.properties文件作為配置文件的原因。
當然還有另一種添加配置文件的策略,因為映射文件和持久化類是一一對應的,可以通過Configuration對象來添加持久化類,讓Hibernate自己來搜索映射文件。
//實例化configuration對象
Configuration cfg = new Configuration()
//多次調用addClass()方法,直接添加持久化類
cfg .addClass(ppp.Item.class)
cfg .addClass(ppp.BId.class);
- 使用hibernate.cfg.xml作為配置文件
下面我們一起來看一個帶有詳細注釋的hibernate.cfg.xml文件:
<!--標準的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的編碼方式-->
<?xml version='1.0'encoding='gb2312'?>
<!--表明解析本XML文件的DTD文檔位置,DTD是DocumentType Definition 的縮寫, 即文檔類型的定義,XML解析器使用DTD文檔來檢查XML文件的合法性。hibernate.sourceforge.net/hibernate-configuration-3.0dtd可以在Hibernate3.1.3軟件包中的src\org\hibernate目錄中找到此文件-->
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!--聲明Hibernate配置文件的開始-->
<hibernate-configuration>
<!--表明以下的配置是針對session-factory配置的,SessionFactory是Hibernate中的一個類,這個類主要負責保存HIbernate的配置信息,以及對Session的操作-->
<session-factory>
<!--配置數據庫的驅動程序,Hibernate在連接數據庫時,需要用到數據庫的驅動程序-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!--設置數據庫的連接url:jdbc:mysql://localhost/hibernate,其中localhost表示mysql服務器名稱,此處為本機,hibernate是數據庫名-->
<property name="hibernate.connection.url"> jdbc:mysql://localhost/hibernate</property>
<!--連接數據庫是用戶名-->
<property name="hibernate.connection.username">root</property>
<!--連接數據庫是密碼-->
<property name="hibernate.connection.password">123456</property>
<!--數據庫連接池的大小-->
<property name="hibernate.connection.pool.size">20</property>
<!--是否在后臺顯示Hibernate用到的SQL語句,開發時設置為true,便于差錯,程序運行時可以在Eclipse的控制臺顯示Hibernate的執行Sql語句。項目部署后可以設置為false,提高運行效率--> <property name="hibernate.show_sql">true</property>
<!--jdbc.fetch_size是指Hibernate每次從數據庫中取出并放到JDBC的Statement中的記錄條數。FetchSize設的越大,讀數據庫的次數越少,速度越快,Fetch Size越小,讀數據庫的次數越多,速度越慢-->
<property name="jdbc.fetch_size">50</property>
<!--jdbc.batch_size是指Hibernate批量插入,刪除和更新時每次操作的記錄數。BatchSize越大,批量操作的向數據庫發送Sql的次數越少,速度就越快,同樣耗用內存就越大--> <property name="jdbc.batch_size">23</property>
<!--jdbc.use_scrollable_resultset是否允許Hibernate用JDBC的可滾動的結果集。對分頁的結果集。對分頁時的設置非常有幫助--> <property name="jdbc.use_scrollable_resultset">false</property>
<!--connection.useUnicode連接數據庫時是否使用Unicode編碼--> <property name="Connection.useUnicode">true</property>
<!--connection.characterEncoding連接數據庫時數據的傳輸字符集編碼方式,最好設置為gbk,用gb2312有的字符不全--> <property name="connection.characterEncoding">gbk</property>
<!--hibernate.dialect 只是Hibernate使用的數據庫方言,就是要用Hibernate連接那種類型的數據庫服務器。-->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect</property>
<!-是否自動創建數據庫表 他主要有一下幾個值:
validate:當sessionFactory創建時,自動驗證或者schema定義導入數據庫。
create:每次啟動都drop掉原來的schema,創建新的。
create-drop:當sessionFactory明確關閉時,drop掉schema。
update(常用):如果沒有schema就創建,有就更新。
-->
<property name="hbm2ddl.auto">create</property>
<!配置此處 sessionFactory.getCurrentSession()可以完成一系列的工作,當調用時, hibernate將session綁定到當前線程,事務結束后,hibernate將session從當前線程中釋放,并且關閉session。當再次調用getCurrentSession()時,將得到一個新的session,并重新開始這一系列工作。-->
<property name="current_session_context_class">thread</property>
<!--指定映射文件為“hibernate/ch1/UserInfo.hbm.xml”--> <mappingresourcemappingresource="org/mxg/UserInfo.hbm.xml">
</session-factory>
</hibernate-configuration>
以上應該是大部分常用的配置文件屬性,當然里面的很多部分都是可以在配置hibernate開發環境時自動生成的,剛開始的時候還是建議大家手動的去配置一下,可以達到熟悉的的時候在用自動生成.
下面我們繼續看一下包含了Hibernate的基本映射信息的配置文件,也就是系統中每一個類與其對應的數據庫表之間的關聯信息,這種配置文件一般命名為:類名.hbm.xml,下面我們通過一個具體的代碼示例來看一下類名.hbm.xml的結構:
<span xmlns="http://www.w3.org/1999/xhtml" style=""><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bzu.hibernate.Student" table="student">
<id name="id" column="id" type="string">
<generator class="uuid"></generator>
</id>
<property name="name" column="name" type="string"></property>
<property name="cardId" column="cardId"type="string"></property>
<property name="age" column="age" type="int"></property>
<set name="courses" table="student_course" cascade="save-update">
<key column="stu_id"></key>
<many-to-many class="com.bzu.hibernate.Course" column="course_id">
</many-to-many>
</set>
</class>
</hibernate-mapping></span>
下面我們一個個標簽進行講解一下:
1.hibernate-mapping
這個元素包括一些可選的屬性。schema和catalog屬性,指明了這個映射所連接(refer)的表所在的schema和/或catalog名稱。假若指定了這個屬性,表名會加上所指定的schema和catalog的名字擴展為全限定名。假若沒有指定,表名就不會使用全限名。 default-cascade指定了未明確注明cascade屬性的Java屬性和集合類Hibernate會采取什么樣的默認級聯風格。auto- import屬性默認讓我們在查詢語言中可以使用非全限定名的類名。
<span xmlns="http://www.w3.org/1999/xhtml" style=""><hibernate-mapping
schema="schemaName" (1)
catalog="catalogName" (2)
default-cascade="cascade_style" (3)
default-access="field|property|ClassName" (4)
default-lazy="true|false" (5)
auto-import="true|false" (6)
package="package.name" (7)
/></span>
(1) schema (可選): 數據庫schema的名稱。 (2) catalog (可選): 數據庫catalog的名稱。 (3) default-cascade (可選 - 默認為 none): 默認的級聯風格。 (4) default-access (可選 - 默認為 property): Hibernate用來訪問所有屬性的策略。可以通過實現PropertyAccessor接口自定義。 (5) default-lazy (可選 - 默認為 true): 指定了未明確注明lazy屬性的Java屬性和集合類, Hibernate會采取什么樣的默認加載風格
(6) auto-import (可選 - 默認為 true): 指定我們是否可以在查詢語言中使用非全限定的類名(僅限于本映射文件中的類)。
(7) package (可選): 指定一個包前綴,如果在映射文檔中沒有指定全限定的類名,就使用這個作為包名。
2.class
使用class元素來定義一個持久化類:
<span xmlns="http://www.w3.org/1999/xhtml" style=""><class
name="ClassName" (1)
table="tableName" (2)
discriminator-value="discriminator_value" (3)
mutable="true|false" (4)
schema="owner" (5)
catalog="catalog" (6)
proxy="ProxyInterface" (7)
dynamic-update="true|false" (8)
dynamic-insert="true|false" (9)
select-before-update="true|false" (10)
polymorphism="implicit|explicit" (11)
where="arbitrary sql where condition" (12)
persister="PersisterClass" (13)
batch-size="N" (14)
optimistic-lock="none|version|dirty|all" (15)
lazy="true|false" (16)
entity-name="EntityName" (17)
check="arbitrary sql check condition" (18)
rowid="rowid" (19)
subselect="SQL expression" (20)
abstract="true|false" (21)
node="element-name"
/></span>
(1) name (可選): 持久化類(或者接口)的Java全限定名。如果這個屬性不存在,Hibernate將假定這是一個非POJO的實體映射。
(2) table (可選 - 默認是類的非全限定名): 對應的數據庫表名。
(3) discriminator-value (可選 - 默認和類名一樣): 一個用于區分不同的子類的值,在多態行為時使用。它可以接受的值包括 null 和 not null。 (4) mutable (可選,默認值為true): 表明該類的實例是可變的或者不可變的。 (5) schema (可選): 覆蓋在根<hibernate-mapping>元素中指定的schema名字。 (6) catalog (可選): 覆蓋在根<hibernate-mapping>元素中指定的catalog名字。 (7) proxy (可選): 指定一個接口,在延遲裝載時作為代理使用。你可以在這里使用該類自己的名字。 (8) dynamic-update (可選, 默認為 false): 指定用于UPDATE 的SQL將會在運行時動態生成,并且只更新那些改變過的字段。 (9) dynamic-insert (可選, 默認為 false): 指定用于INSERT的 SQL 將會在運行時動態生成,并且只包含那些非空值字段。 (10) select-before-update (可選, 默認為 false): 指定Hibernate除非確定對象真正被修改了(如果該值為true-譯注),否則不會執行SQL UPDATE操作。在特定場合(實際上,它只在一個瞬時對象(transient object)關聯到一個新的session中時執行的update()中生效),這說明Hibernate會在UPDATE 之前執行一次額外的SQL SELECT操作,來決定是否應該執行 UPDATE。 (11) polymorphism(多態) (可選, 默認值為 implicit (隱式) ): 界定是隱式還是顯式的使用多態查詢(這只在Hibernate的具體表繼承策略中用到-譯注)。 (12) where (可選) 指定一個附加的SQLWHERE 條件,在抓取這個類的對象時會一直增加這個條件。 (13) persister (可選): 指定一個定制的ClassPersister。
(14) batch-size (可選,默認是1) 指定一個用于根據標識符(identifier)抓取實例時使用的"batch size"(批次抓取數量)。
(15) optimistic-lock(樂觀鎖定) (可選,默認是version): 決定樂觀鎖定的策略。
(16) lazy (可選): 通過設置lazy="false",所有的延遲加載(Lazyfetching)功能將被全部禁用(disabled)。
(17) entity-name (可選,默認為類名): Hibernate3允許一個類進行多次映射(前提是映射到不同的表),并且允許使用Maps或XML代替Java層次的實體映射(也就是實現動態領域模型,不用寫持久化類-譯注)。 (18) check (可選): 這是一個SQL表達式,用于為自動生成的schema添加多行(multi-row)約束檢查。 (19) rowid (可選):Hibernate可以使用數據庫支持的所謂的ROWIDs,例如: Oracle數據庫,如果你設置這個可選的rowid, Hibernate可以使用額外的字段rowid實現快速更新。ROWID是這個功能實現的重點,它代表了一個存儲元組(tuple)的物理位置。 (20) subselect (可選): 它將一個不可變(immutable)并且只讀的實體映射到一個數據庫的子查詢中。當你想用視圖代替一張基本表的時候,這是有用的,但最好不要這樣做。更多的介紹請看下面內容。
(21) abstract (可選): 用于在<union-subclass>的繼承結構(hierarchies)中標識抽象超類。
3.id
被映射的類必須定義對應數據庫表主鍵字段。大多數類有一個JavaBeans風格的屬性,為每一個實例包含唯一的標識。<id> 元素定義了該屬性到數據庫表主鍵字段的映射。
<id
name="propertyName" (1)
type="typename" (2)
column="column_name" (3)
unsaved-value="null|any|none|undefined|id_value" (4)
access="field|property|ClassName" (5)
length="L" (6)
<generatorclassgeneratorclass="generatorClass"/>
</id>
(1) name (可選): 標識屬性的名字。
(2) type (可選): 標識Hibernate類型的名字。(如果沒配置,hibernate將會自動轉化成相應的數據庫類型)
(3) column (可選 - 默認為屬性名): 主鍵字段的名字。
(4) unsaved-value (可選 - 默認為一個切合實際(sensible)的值): 一個特定的標識屬性值,用來標志該實例是剛剛創建的,尚未保存。這可以把這種實例和從以前的session中裝載過(可能又做過修改--譯者注)但未再次持久化的實例區分開來。 (5) access (可選 - 默認為property): Hibernate用來訪問屬性值的策略。 (6)length="L"指定長度
4.Generator
可選的<generator>子元素是一個Java類的名字,用來為該持久化類的實例生成唯一的標識。如果這個生成器實例需要某些配置值或者初始化參數,用<param>元素來傳遞。
<id name="id"type="long" column="cat_id">
<generator class="org.hibernate.id.TableHiLoGenerator">
<param name="table">uid_table</param>
<param name="column">next_hi_value_column</param>
</generator>
</id>
所有的生成器都實現org.hibernate.id.IdentifierGenerator接口。這是一個非常簡單的接口;某些應用程序可以選擇提供他們自己特定的實現。當然, Hibernate提供了很多內置的實現。
下面是一些內置生成器的快捷名字:
increment
用于為long, short或者int類型生成唯一標識。只有在沒有其他進程往同一張表中插入數據時才能使用。在集群下不要使用。
identity
對DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的內置標識字段提供支持。返回的標識符是long, short 或者int類型的
。 sequence
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的標識符是long, short或者 int類型的。
hilo
使用一個高/低位算法高效的生成long, short 或者 int類型的標識符。給定一個表和字段(默認分別是 hibernate_unique_key 和next_hi)作為高位值的來源。高/低位算法生成的標識符只在一個特定的數據庫中是唯一的。
seqhilo
使用一個高/低位算法來高效的生成long, short 或者 int類型的標識符,給定一個數據庫序列(sequence)的名字。
uuid
用一個128-bit的UUID算法生成字符串類型的標識符,這在一個網絡中是唯一的(使用了IP地址)。UUID被編碼為一個32位16進制數字的字符串。
guid
在MS SQL Server 和 MySQL 中使用數據庫生成的GUID字符串
native
根據底層數據庫的能力選擇identity, sequence 或者hilo中的一個
assigned
讓應用程序在save()之前為對象分配一個標示符。這是 <generator>元素沒有指定時的默認生成策略。手動分配主鍵的時候要設置成它
select
通過數據庫觸發器選擇一些唯一主鍵的行并返回主鍵值來分配一個主鍵。
foreign
使用另外一個相關聯的對象的標識符。通常和<one-to-one>聯合起來使用。
- property
<property>元素為類定義了一個持久化的,JavaBean風格的屬性。
<span xmlns="http://www.w3.org/1999/xhtml" style=""><property
name="propertyName" (1)
column="column_name" (2)
type="typename" (3)
update="true|false" (4)
insert="true|false" (4)
formula="arbitrary SQL expression"(5)
access="field|property|ClassName"(6)
lazy="true|false" (7)
unique="true|false" (8)
not-null="true|false" (9)
optimistic-lock="true|false" (10)
generated="never|insert|always" (11)
node="element-name|@attribute-name|element/@attribute|."
index="index_name"
unique_key="unique_key_id"
length="L"
precision="P"
scale="S"
/>
</span>

(1) name: 屬性的名字,以小寫字母開頭。
(2) column (可選 - 默認為屬性名字): 對應的數據庫字段名。也可以通過嵌套的<column>元素指定。
(3) type (可選): 一個Hibernate類型的名字。
(4) update, insert (可選 - 默認為 true) : 表明用于UPDATE 和/或 INSERT 的SQL語句中是否包含這個被映射了的字段。這二者如果都設置為false 則表明這是一個“外源性(derived)”的屬性,它的值來源于映射到同一個(或多個)字段的某些其他屬性,或者通過一個trigger(觸發器)或其他程序生成。
(5) formula (可選): 一個SQL表達式,定義了這個計算(computed)屬性的值。計算屬性沒有和它對應的數據庫字段。
(6) access (可選 - 默認值為 property): Hibernate用來訪問屬性值的策略。
(7) lazy (可選 - 默認為 false): 指定指定實例變量第一次被訪問時,這個屬性是否延遲抓取(fetched lazily)(需要運行時字節碼增強)。
(8) unique (可選): 使用DDL為該字段添加唯一的約束。同樣,允許它作為property-ref引用的目標。
(9) not-null (可選): 使用DDL為該字段添加可否為空(nullability)的約束。
(10) optimistic-lock (可選 - 默認為 true): 指定這個屬性在做更新時是否需要獲得樂觀鎖定(optimistic lock)。換句話說,它決定這個屬性發生臟數據時版本(version)的值是否增長。
(11) generated (可選 - 默認為 never): 表明此屬性值是否實際上是由數據庫生成的。
access屬性用來讓你控制Hibernate如何在運行時訪問屬性。默認情況下,Hibernate會使用屬性的get/set方法對。如果你指明access="field",則Hibernate會忽略get/set方法對,直接使用反射來訪問成員變量。
formula屬性是個特別強大的的特征。這些屬性應該定義為只讀,屬性值在裝載時計算生成。用一個SQL表達式生成計算的結果,它會在這個實例轉載時翻譯成一個SQL查詢的SELECT子查詢語句。如:
<property name="totalPrice" formula="(SELECT SUM(*) FROM user)" />
Hibernate基本類型名(比如:integer, string, character,date, timestamp,float, binary, serializable, object, blob)。
一個Java類的名字,這個類屬于一種默認基礎類型 (比如: int, float,char, java.lang.String, java.util.Date,java.lang.Integer, java.sql.Clob)。
一個可以序列化的Java類的名字。
一個自定義類型的類的名字。(比如: com.illflow.type.MyCustomType)。
基本值類型(Hibernate內建立自己的類型,從java轉化成數據庫類型) string:從java.lang.String 到 VARCHAR (或者 Oracle的 VARCHAR2)的映射。
date, time, timestamp:從java.util.Date和其子類到SQL類型DATE, TIME 和TIMESTAMP (或等價類型)的映射。
calendar, calendar_date:從java.util.Calendar 到SQL 類型TIMESTAMP和 DATE(或等價類型)的映射。
big_decimal, big_integer:從java.math.BigDecimal和java.math.BigInteger到NUMERIC (或者 Oracle 的NUMBER類型)的映射。
locale, timezone, currency:從java.util.Locale, java.util.TimeZone 和java.util.Currency 到VARCHAR (或者 Oracle 的VARCHAR2類型)的映射. Locale和 Currency 的實例被映射為它們的ISO代碼。TimeZone的實例被影射為它的ID。
Class:從java.lang.Class 到 VARCHAR (或者 Oracle 的VARCHAR2類型)的映射。Class被映射為它的全限定名。
Binary:把字節數組(byte arrays)映射為對應的 SQL二進制類型。
Text:把長Java字符串映射為SQL的CLOB或者TEXT類型。
Serializable:把可序列化的Java類型映射到對應的SQL二進制類型。你也可以為一個并非默認為基本類型的可序列化Java類或者接口指定Hibernate類型serializable。
clob, blob:JDBC 類 java.sql.Clob 和 java.sql.Blob的映射。某些程序可能不適合使用這個類型,因為blob和clob對象可能在一個事務之外是無法重用的。(而且, 驅動程序對這種類型的支持充滿著補丁和前后矛盾。)