本文中將講述Hibernate的基本配置及配置文件的應用,這對於正確熟練使用Hibernate是相當關鍵的。
配置文件中映射元素詳解
對象關系的映射是用一個XML文檔來說明的。映射文檔可以使用工具來生成,如XDoclet,Middlegen和AndroMDA等。下面從一個映射的例子開始講解映射元素,映射文件的代碼如下。
<?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 定長字符
2、自定義映射類型
Hibernate提供了自定義映射類型接口,允許用戶以編程的方式創建自定義的映射類型。用戶自定義的映射類型需要實現net.sf.hibernate.UserType或net.sf.hibernate.CompositeUserType接口。具體的創建自定義映射類型的方法請參考hibernate官方文檔或相關資料,這裡不再詳細介紹。