Java程式設計師從笨鳥到菜鳥之(五十三)細談Hibernate(四)Hibernate常用配置檔案詳解
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
初學hibernate的童鞋,剛開應該都有這種感覺,hibernate的配置檔案好麻煩,還不如jdbc訪問資料庫呢,直接寫程式碼,多方便,用hibernate還要寫程式碼,還要寫配置,太麻煩了。至少我剛開始學習的時候就是這麼想的。配置檔案確實有他枯燥的一面,但等你真正深入學習的時候,你就可以發現他枯燥的背後卻藏著很多強大的功能,呵呵,讓我說的這麼玄乎,那就讓我們一起來看看吧,讓我們一起來見證一下這些配置檔案的強大。
Hibernate中配置主要分為兩種:一種包含了Hibernate與資料庫的基本連線資訊,在Hibernate工作的初始階段,這些資訊被先後載入到Configuration和SessionFactory例項;另一種包含了Hibernate的基本對映資訊,即系統中每一個類與其對應的資料庫表之間的關聯資訊,在Hibernate工作的初始階段,這些資訊通過hibernate.cfg.xml的mapping節點被載入到Configuration和SessionFactory例項。這兩種檔案資訊包含了Hibernate的所有執行期引數。下面我們用詳細的例子來說明這兩種檔案的基本結構和內容。
實現包含了Hibernate與資料庫的基本連線資訊的配置方式有兩種方式:
第一種是使用hibernate.properties檔案作為配置檔案。
第二種是使用hibernate.cfg.xml檔案作為配置檔案。
1. 使用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);
2. 使用hibernate.cfg.xml作為配置檔案
關於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> <!--資料庫連線池的大小--> <propertyname="hibernate.connection.pool.size">20</property> <!--是否在後臺顯示Hibernate用到的SQL語句,開發時設定為true,便於差錯,程式執行時可以在Eclipse的控制檯顯示Hibernate的執行Sql語句。專案部署後可以設定為false,提高執行效率--> <propertyname="hibernate.show_sql">true</property> <!--jdbc.fetch_size是指Hibernate每次從資料庫中取出並放到JDBC的Statement中的記錄條數。FetchSize設的越大,讀資料庫的次數越少,速度越快,Fetch Size越小,讀資料庫的次數越多,速度越慢--> <propertyname="jdbc.fetch_size">50</property> <!--jdbc.batch_size是指Hibernate批量插入,刪除和更新時每次操作的記錄數。BatchSize越大,批量操作的向資料庫傳送Sql的次數越少,速度就越快,同樣耗用記憶體就越大--> <propertyname="jdbc.batch_size">23</property> <!--jdbc.use_scrollable_resultset是否允許Hibernate用JDBC的可滾動的結果集。對分頁的結果集。對分頁時的設定非常有幫助--> <propertyname="jdbc.use_scrollable_resultset">false</property> <!--connection.useUnicode連線資料庫時是否使用Unicode編碼--> <propertyname="Connection.useUnicode">true</property> <!--connection.characterEncoding連線資料庫時資料的傳輸字符集編碼方式,最好設定為gbk,用gb2312有的字元不全--> <propertyname="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就建立,有就更新。--> <propertyname="hbm2ddl.auto">create</property> <!配置此處 sessionFactory.getCurrentSession()可以完成一系列的工作,當呼叫時,hibernate將session繫結到當前執行緒,事務結束後,hibernate將session從當前執行緒中釋放,並且關閉session。當再次呼叫getCurrentSession()時,將得到一個新的session,並重新開始這一系列工作。--><propertyname="current_session_context_class">thread</property><!--指定對映檔案為“hibernate/ch1/UserInfo.hbm.xml”--> <mappingresource="org/mxg/UserInfo.hbm.xml"> </session-factory> </hibernate-configuration>
以上應該是大部分常用的配置檔案屬性,當然裡面的很多部分都是可以在配置hibernate開發環境時自動生成的,剛開始的時候還是建議大家手動的去配置一下,可以達到熟悉的的時候在用自動生成
下面我們繼續看一下包含了Hibernate的基本對映資訊的配置檔案,也就是系統中每一個類與其對應的資料庫表之間的關聯資訊,這種配置檔案一般命名為:類名.hbm.xml,下面我們通過一個具體的程式碼示例來看一下類名.hbm.xml的結構:
<?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>
下面我們一個個標籤進行講解一下:
1.hibernate-mapping
這個元素包括一些可選的屬性。schema和catalog屬性,指明瞭這個對映所連線(refer)的表所在的schema和/或catalog名稱。假若指定了這個屬性,表名會加上所指定的schema和catalog的名字擴充套件為全限定名。假若沒有指定,表名就不會使用全限定名。 default-cascade指定了未明確註明cascade屬性的Java屬性和集合類Hibernate會採取什麼樣的預設級聯風格。auto- import屬性預設讓我們在查詢語言中可以使用非全限定名的類名。
<hibernate-mappingschema="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)/>
(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 元素來定義一個持久化類:
<classname="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"/>
(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>元素定義了該屬性到資料庫表主鍵欄位的對映。
<idname="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)<generatorclass="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"> <generatorclass="org.hibernate.id.TableHiLoGenerator"> <paramname="table">uid_table</param> <paramname="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> 聯合起來使用。
5. property
<property> 元素為類定義了一個持久化的 ,JavaBean 風格的屬性。
<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" />
(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): 表明此屬性值是否實際上是由資料庫生成的。
typename可以是如下幾種:
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