Hibernate配置文件和映射元素詳解

<!--標準的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的編碼方式-->
            
     <?xml version='1.0' encoding='gb2312'?>
<!--表明解析本XML文件的DTD文檔位置,DTD是Document Type 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在連接數據庫時,需要用到數據庫的驅動程序--

<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
>
           <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</hibernate>
    <!--連接數據庫是用戶名-->
           <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中的記錄條數。Fetch Size設的越大,讀數據庫的次數越少,速度越快,Fetch Size越小,讀數據庫的次數越多,速度越慢-->
         <property name="jdbc.fetch_size">50</property>
         <!--jdbc.batch_size是指Hibernate批量插入,刪除和更新時每次操作的記錄數。Batch Size越大,批量操作的向數據庫發送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>
         <!--指定映射文件爲“hibernate/ch1/UserInfo.hbm.xml”-->         
       
    <mapping resource="org/mxg/UserInfo.hbm.xml">
 
 </session-factory>
  </hibernate-configuration>   

 

配置文件中映射元素詳解

對象關係的映射是用一個XML文檔來說明的。映射文檔可以使用工具來生成,如XDoclet,Middlegen和AndroMDA等。下面從一個映射的例子開始講解映射元素,映射文件的代碼如下。

<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

<?xml version="1.0"?>

<!--

所有的XML映射文件都需要定義如下所示的DOCTYPE。

Hibernate會先在它的類路徑(classptah)中搜索DTD文件。

-->

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!--

hibernate-mapping有幾個可選的屬性:

schema屬性指明瞭這個映射的表所在的schema名稱。

default-cascade屬性指定了默認的級聯風格 可取值有 none、save、update。

auto-import屬性默認讓我們在查詢語言中可以使用非全限定名的類名 可取值有 true、false。

package屬性指定一個包前綴。

-->

<hibernate-mapping schema="schemaName" default-cascade="none"

auto-import="true" package="test">

<!--用class元素來定義一個持久化類 -->

<class name="People" table="person">

<!-- id元素定義了屬性到數據庫表主鍵字段的映射。-->

<id name="id">

<!-- 用來爲該持久化類的實例生成唯一的標識 -->

<generator class="native"/>

</id>

<!-- discriminator識別器 是一種定義繼承關係的映射方法-->

<discriminator column="subclass" type="character"/>

<!-- property元素爲類聲明瞭一個持久化的,JavaBean風格的屬性-->

<property name="name" type="string">

<column name="name" length="64" not-null="true" />

</property>

<property name="sex"

not-null="true"

update="false"/>

<!--多對一映射關係-->

<many-to-one name="friend"

column="friend_id"

update="false"/>

<!--設置關聯關係-->

<set name="friends" inverse="true" order-by="id">

<key column="friend_id"/>

<!—一對多映射-->

<one-to-many class="Cat"/>

</set>

</class>

</hibernate-mapping>

組件應用的方法

組件有兩種類型,即組件(component)和動態組件(dynamic-component)。在配置文件中,component元素爲子對象的元素與父類對應表的字段建立起映射關係。然後組件可以聲明它們自己的屬性、組件或者集合。component元素的定義如下所示:

<component name="propertyName" class="className" insert="true|false"

upate="true|false" access="field|property|ClassName">

<property ...../>

<many-to-one .... />

........

</component>

在這段代碼中,name是指屬性名,class是類的名字,insert指的是被映射的字段是否出現在SQL的INSERT語句中,upate指出被映射的字段是否出現在SQL的UPDATE語句中,access指出訪問屬性的策略。

Hiebernate的基本配置

Hibernate的數據庫連接信息是從配置文件中加載的。Hibernate的配置文件有兩種形式:一種是XML格式的文件,一種是properties屬性文件。properties形式的配置文件默認文件名是hibernate.properties,一個properties形式的配置文件內容如下所示:

#指定數據庫使用的驅動類

hibernate.connection.driver_class = com.mysql.jdbc.Driver r

#指定數據庫連接串

hibernate.connection.url = jdbc:mysql://localhost:3306/db

#指定數據庫連接的用戶名

hibernate.connection.username = user

#指定數據庫連接的密碼

hibernate.connection.password = password

#指定數據庫使用的方言

hibernate.dialect = net.sf.hibernate.dialect.MySQLDialect

#指定是否打印SQL語句

hibernate.show_sql=true

在配置文件中包含了一系列屬性的配置,Hibernate將根據這些屬性來連接數據庫。

在XML格式的配置文件中,除了基本的Hibernate配置信息,還可以指定具體的持久化類的映射文件,這可以避免將持久化類的配置文件硬編碼在程序中。XML格式的配置文件的默認文件名爲hibernate.cfg.xml,一個XML配置文件的示例如下所示:

<?xml version=''1.0'' encoding=''UTF-8''?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!--顯示執行的SQL語句-->

<property name="show_sql">true</property>

<!--連接字符串-->

<property name="connection.url">jdbc:mysql://localhost:3306/STU</property>

<!--連接數據庫的用戶名-->

<property name="connection.username">root</property>

<!--數據庫用戶密碼-->

<property name="connection.password">root</property>

<!--數據庫驅動-->

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>

<!--選擇使用的方言-->

<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!--映射文件 -->

<mapping resource="com/stuman/domain/Admin.hbm.xml" />

<!--映射文件-->

<mapping resource="com/stuman/domain/Student.hbm.xml" />

</session-factory>

</hibernate-configuration>

properties形式的配置文件和XML格式的配置文件可以同時使用。當同時使用兩種類型的配置文件時,XML配置文件中的設置會覆蓋properties配置文件的相同的屬性。

 

 

 

對象標識符號

在關係數據庫表中,主鍵(Primary Key)用來識別記錄,並保證每條記錄的唯一性。在Java語言中,通過比較兩個變量所引用對象的內存地址是否相同,或者比較兩個變量引用的對象值是否相同來判斷兩對象是否相等。Hibernate爲了解決兩者之間的不同,使用對象標識符(OID)來標識對象的唯一性。OID是關係數據庫中主鍵在Java對象模型中的等價物。在運行時,Hibernate根據OID來維持Java對象和數據庫表中記錄的對應關係。如下代碼所示,三次調用了Session的load()方法,分別加載OID爲1或3的User對象。

Transaction tx = session.beginTransaction();

User user1 = (User)session.load(User.class,new Long(1));

User user2 = (User)session.load(User.class,new Long(1));

User user3 = (User)session.load(User.class,new Long(3));

System.out.println( user1 == user2 );

System.out.println( user1 == user3 );

應用程序在執行上述代碼時,第一次加載OID爲1的User對象,從數據庫中查找ID爲1的記錄,然後創建相應的User實例,並把它保存在Session緩存中,最後將該實例的引用賦值給變量user1。第二次加載OID爲1的對象時,直接把Session緩存中OID爲1的實例的引用賦值給變量user2。因此,表達式user1==user2的結果爲true。

標識的生成可以使用不同的策略,表1爲Hibernate內置的標識生成策略。

表1:Hibernate標識生成策略

標識符生成器 描述
increment 適用於代理主鍵。由Hibernate自動以遞增方式生成。
identity 適用於代理主鍵。由底層數據庫生成標識符。
sequence 適用於代理主鍵。Hibernate根據底層數據庫的序列生成標識符,這要求底層數據庫支持序列。
hilo 適用於代理主鍵。Hibernate分局high/low算法生成標識符。
seqhilo 適用於代理主鍵。使用一個高/低位算法來高效的生成long,short或者int類型的標識符。
native 適用於代理主鍵。根據底層數據庫對自動生成標識符的方式,自動選擇identity、sequence或hilo。
uuid.hex 適用於代理主鍵。Hibernate採用128位的UUID算法生成標識符。
uuid.string 適用於代理主鍵。UUID被編碼成一個16字符長的字符串。
assigned 適用於自然主鍵。由Java應用程序負責生成標識符。
foreign 適用於代理主鍵。使用另外一個相關聯的對象的標識符。

Hibernate映射類型

在對象/關係映射文件中,Hibernate採用映射類型作爲Java類型和SQL類型的橋樑。Hibernate映射類型分爲2種:內置映射類型和自定義映射類型。

1、內置映射類型

Hibernate對所有的Java原生類型、常用的Java類型如String、Date等都定義了內置的映射類型。表2列出了Hibernate映射類型、對應的Java類型以及對應的標準SQL類型。

表2:Hibernate內置映射類型

Hibernate映射類型 Java類型 標準SQL類型 大小
integer/int java.lang.Integer/int INTEGER 4字節
long java.lang.Long/long BIGINT 8字節
short java.lang.Short/short SMALLINT 2字節
byte java.lang.Byte/byte TINYINT 1字節
float java.lang.Float/float FLOAT 4字節
double java.lang.Double/double DOUBLE 8字節
big_decimal java.math.BigDecimal NUMERIC  
character java.lang.Character/java.lang.String/char CHAR(1) 定長字符
string java.lang.String VARCHAR 變長字符
boolean/ yes_no/true_false java.lang.Boolean/Boolean BIT 布爾類型
date java.util.Date/java.sql.Date DATE 日期
timestamp java.util.Date/java.util.Timestamp TIMESTAMP 日期
calendar java.util.Calendar TIMESTAMP 日期
calendar_date java.util.Calendar DATE 日期
binary byte[] BLOB

BLOB
text java.lang.String TEXT CLOB
serializable 實現java.io.Serializablej接口的任意Java類 BLOB BLOB
clob java.sql.Clob CLOB CLOB
blob java.sql.Blob BLOB BLOB
class java.lang.Class VARCHAR 定長字符
locale java.util.Locale VARCHAR 定長字符
timezone java.util.TimeZone VARCHAR 定長字符
currency java.util.Currency VARCHAR 定長字符

hibernate-mapping
這個元素包括三個可選的屬性。schema屬性,指明瞭這個映射所引用的表所在的schema名稱。假若指定了這個屬性,表名會加上所指定的schema的名字擴展爲全限定名。假若沒有指定,表名就不會使用全限定名。default-cascade指定了未明確註明cascade屬性的Java屬性和集合類Java會採取什麼樣的默認級聯風格。auto-import屬性默認讓我們在查詢語言中可以使用非全限定名的類名。

<hibernate-mapping
         schema="schemaName"                         
         default-cascade="none|save-update"          
         auto-import="true|false"                    
         package="package.name"                      
 />
 schema (可選): 數據庫schema名稱。
 
 default-cascade (可選 - 默認爲 none): 默認的級聯風格。
 
 auto-import (可選 - 默認爲 true): 指定是否我們可以在查詢語言中使用非全限定的類名(僅限於本映射文件中的類)。
 
 package (可選): 指定一個包前綴,如果在映射文檔中沒有指定全限定名,就使用這個包名。 
 

假若你有兩個持久化類,它們的非全限定名是一樣的(就是在不同的包裏面--譯者注),你應該設置auto-import="false"。假若說你把一個“import過”的名字同時對應兩個類, Hibernate會拋出一個異常。

5.1.3. class
你可以使用class元素來定義一個持久化類:

<class
        name="ClassName"                             
        table="tableName"                            
        discriminator-value="discriminator_value"    
        mutable="true|false"                         
        schema="owner"                               
        proxy="ProxyInterface"                       
        dynamic-update="true|false"                  
        dynamic-insert="true|false"                  
        select-before-update="true|false"            
        polymorphism="implicit|explicit"             
        where="arbitrary sql where condition"         (11)
        persister="PersisterClass"                    (12)
        batch-size="N"                                (13)
        optimistic-lock="none|version|dirty|all"      (14)
        lazy="true|false"                             (15)
/>
 name: 持久化類(或者接口)的Java全限定名。
 
 table: 對應的數據庫表名。
 
 discriminator-value(辨別值) (可選 - 默認和類名一樣):一個用於區分不同的子類的值,在多態行爲時使用。
 
 mutable(可變) (可選, 默認值爲 true): 表明該類的實例可變(不可變)。
 
 schema (可選): 覆蓋在根<hibernate-mapping>元素中指定的schema名字。
 
 proxy (可選): 指定一個接口,在延遲裝載時作爲代理使用。你可以在這裏使用該類自己的名字。
 
 dynamic-update(動態更新) (可選,默認爲false): 指定用於UPDATE 的SQL將會在運行時動態生成,並且只更新那些改變過的字段。
 
 dynamic-insert(動態插入) (可選, 默認爲false): 指定用於INSERT的 SQL 將會在運行時動態生成,並且只包含那些非空值字段。
 
 select-before-update (可選,默認值爲false): 指定Hibernate除非確定對象的確被修改了,不會執行SQL UPDATE操作。在特定場合(實際上,只會發生在一個臨時對象關聯到一個新的session中去,執行update()的時候),這說明Hibernate會在UPDATE之前執行一次額外的SQL SELECT操作,來決定是否應該進行UPDATE。
 
 polymorphism(多形,多態) (可選, 默認值爲 implicit (隱式)): 界定是隱式還是顯式的使用查詢多態。
 
(11) where (可選) 指定一個附加的SQLWHERE 條件,在抓取這個類的對象時會一直增加這個條件。
 
(12) persister (可選): 指定一個定製的ClassPersister。
 
(13) batch-size (可選,默認是1) 指定一個用於根據標識符抓取實例時使用的"batch size"(批次抓取數量)。
 
(14) optimistic-lock(樂觀鎖定) (可選,默認是version): 決定樂觀鎖定的策略。
 
(15) lazy(延遲) (可選): 假若設置 lazy="true",就是設置這個類自己的名字作爲proxy接口的一種等價快捷形式。 
 

若指明的持久化類實際上是一個接口,也可以被完美地接受。其後你可以用<subclass>來指定該接口的實際實現類名。你可以持久化任何static(靜態的)內部類。記得應該使用標準的類名格式,就是說比如:Foo$Bar。

不可變類,mutable="false"不可以被應用程序更新或者刪除。這可以讓Hibernate做一些小小的性能優化。

可選的proxy屬性可以允許延遲加載類的持久化實例。Hibernate開始會返回實現了這個命名接口的CGLIB代理。當代理的某個方法被實際調用的時候,真實的持久化對象纔會被裝載。參見下面的“用於延遲裝載的代理”。

Implicit (隱式)的多態是指,如果查詢中給出的是任何超類、該類實現的接口或者該類的名字,都會返回這個類的實例;如果查詢中給出的是子類的名字,則會返回子類的實例。 Explicit (顯式)的多態是指,只有在查詢中給出的明確是該類的名字時纔會返回這個類的實例;同時只有當在這個<class>的定義中作爲<subclass>或者<joined-subclass>出現的子類,纔會可能返回。大多數情況下,默認的polymorphism="implicit"都是合適的。顯式的多態在有兩個不同的類映射到同一個表的時候很有用。(允許一個“輕型”的類,只包含部分表字段)。

persister屬性可以讓你定製這個類使用的持久化策略。你可以指定你自己實現的net.sf.hibernate.persister.EntityPersister的子類,你甚至可以完全從頭開始編寫一個net.sf.hibernate.persister.ClassPersister接口的實現,可能是用儲存過程調用、序列化到文件或者LDAP數據庫來實現的。參閱net.sf.hibernate.test.CustomPersister,這是一個簡單的例子(“持久化”到一個Hashtable)。

請注意dynamic-update和dynamic-insert的設置並不會繼承到子類,所以在<subclass>或者<joined-subclass>元素中可能需要再次設置。這些設置是否能夠提高效率要視情形而定。請用你的智慧決定是否使用。

使用select-before-update通常會降低性能.當是在防止數據庫不必要的觸發update觸發器,這就很有用了。

如果你打開了dynamic-update,你可以選擇幾種樂觀鎖定的策略:

version(版本檢查)檢查version/timestamp字段

all(全部) 檢查全部字段

dirty(髒檢查)只檢察修改過的字段

none(不檢查)不使用樂觀鎖定

我們非常強烈建議你在Hibernate中使用version/timestamp字段來進行樂觀鎖定。對性能來說,這是最好的選擇,並且這也是唯一能夠處理在session外進行操作的策略(就是說,當使用Session.update()的時候)。

5.1.4. id
被映射的類必須聲明對應數據庫表主鍵字段。大多數類有一個JavaBeans風格的屬性,爲每一個實例包含唯一的標識。<id> 元素定義了該屬性到數據庫表主鍵字段的映射。

<id
        name="propertyName"                     
        type="typename"                         
        column="column_name"                    
        unsaved-value="any|none|null|id_value"  
        access="field|property|ClassName">      

        <generator class="generatorClass"/>
</id>
 name (可選): 標識屬性的名字。
 
 type (可選): 標識Hibernate類型的名字。
 
 column (可選 - 默認爲屬性名): 主鍵字段的名字。
 
 unsaved-value (可選 - 默認爲null): 一個特定的標識屬性值,用來標誌該實例是剛剛創建的,尚未保存。這可以把這種實例和從以前的session中裝載過(可能又做過修改--譯者注)但未再次持久化的實例區分開來。
 
 access (可選 - 默認爲property): Hibernate用來訪問屬性值的策略。 
 

如果 name屬性不存在,會認爲這個類沒有標識屬性。

unsaved-value 屬性很重要!如果你的類的標識屬性不是默認爲null的,你應該指定正確的默認值。

還有一個另外的<composite-id>聲明可以訪問舊式的多主鍵數據。我們強烈不鼓勵使用這種方式。

5.1.4.1. generator
必須聲明的<generator>子元素是一個Java類的名字,用來爲該持久化類的實例生成唯一的標識。如果這個生成器實例需要某些配置值或者初始化參數,用<param>元素來傳遞。

<id name="id" type="long" column="uid" unsaved-value="0">
        <generator class="net.sf.hibernate.id.TableHiLoGenerator">
                <param name="table">uid_table</param>
                <param name="column">next_hi_value_column</param>
        </generator>
</id>
所有的生成器都實現net.sf.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)作爲高位值得來源。高/低位算法生成的標識符只在一個特定的數據庫中是唯一的。在使用JTA獲得的連接或者用戶自行提供的連接中,不要使用這種生成器。

seqhilo(使用序列的高低位)
使用一個高/低位算法來高效的生成long, short或者 int類型的標識符,給定一個數據庫序列(sequence)的名字。

uuid.hex
用一個128-bit的UUID算法生成字符串類型的標識符。在一個網絡中唯一(使用了IP地址)。UUID被編碼爲一個32位16進制數字的字符串。

uuid.string
使用同樣的UUID算法。UUID被編碼爲一個16個字符長的任意ASCII字符組成的字符串。不能使用在PostgreSQL數據庫中

native(本地)
根據底層數據庫的能力選擇identity, sequence 或者hilo中的一個。

assigned(程序設置)
讓應用程序在save()之前爲對象分配一個標示符。

foreign(外部引用)
使用另外一個相關聯的對象的標識符。和<one-to-one>聯合一起使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章