飛艷小屋

          程序--人生--哲學___________________歡迎艷兒的加入

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            52 Posts :: 175 Stories :: 107 Comments :: 0 Trackbacks
          Hibernate技術全面學習

          1. hibernate核心接口

          在項目種使用Hibernate框架,非常關鍵的一點就是要了解Hibernate的核心接口。Hibernate 接口位于業務層和持久化層。

          圖1 Hibernate核心接口的層次架構關系

            Hibernate的核心接口一共有5個,分別為:Session、 SessionFactory、Transaction、Query和Configuration。這5個核心接口在任何開發中都會用到。通過這些接口,不僅可以對持久化對象進行存取,還能夠進行事務控制。下面對這五的核心接口分別加以介紹。

          • Session接口:Session接口負責執行被持久化對象的CRUD操作(CRUD的任務是完成與數據庫的交流,包含了很多常見的SQL語句。)。但需要注意的是Session對象是非線程安全的。同時,Hibernate的session不同于JSP應用中的HttpSession。這里當使用session這個術語時,其實指的是 Hibernate中的session,而以后會將HttpSesion對象稱為用戶session。
          • SessionFactory接口:SessionFactroy接口負責初始化Hibernate。它充當數據存儲源的代理,并負責創建 Session對象。這里用到了工廠模式。需要注意的是SessionFactory并不是輕量級的,因為一般情況下,一個項目通常只需要一個 SessionFactory就夠,當需要操作多個數據庫時,可以為每個數據庫指定一個SessionFactory。
          • Configuration接口:Configuration接口負責配置并啟動Hibernate,創建SessionFactory對象。在 Hibernate的啟動的過程中,Configuration類的實例首先定位映射文檔位置、讀取配置,然后創建SessionFactory對象。
          • Transaction接口:Transaction接口負責事務相關的操作。它是可選的,可發人員也可以設計編寫自己的底層事務處理代碼。
          • Query和Criteria接口:Query和Criteria接口負責執行各種數據庫查詢。它可以使用HQL語言或SQL語句兩種表達方式。
          /**

          ?簡單應用

          ??????? SessionFactory sf = new Configuration().configure().buildSessionFactory();
          ??? ??? Session session = sf.openSession();
          ??? ??? Transaction tx = session.beginTransaction();
          ??? ??? User user = new User();
          ??? ??? ???
          ??? ??? user.setUsername("starxing");
          ??? ??? user.setEmail("star_xing@126.com");
          ??? ??? user.setPassword("starixng");
          ??? ??? session.save(user);
          ??? ??? tx.commit();
          ??? ??? session.close();
          **/

          2. Hibernate 的配置文件應用。


          2.1? 配置文件中映射元素詳解

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

          <?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屬性指定了默認的級聯風格可取值有 nonesaveupdate
          auto-import屬性默認讓我們在查詢語言中可以使用非全限定名的類名可取值有 truefalse
          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>

          2.2? 組件應用的方法

          組件有兩種類型,即組件(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指的是被映射的字段是否出現在SQLINSERT語句中,upate指出被映射的字段是否出現在SQLUPDATE語句中,access指出訪問屬性的策略。

          2.3? 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配置文件的相同的屬性。

          2.4? 對象標識符號

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

          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 );

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

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

          4.1? Hibernate標識生成策略

          標識符生成器

          描述

          increment

          適用于代理主鍵。由Hibernate自動以遞增方式生成。

          identity

          適用于代理主鍵。由底層數據庫生成標識符。

          sequence

          適用于代理主鍵。Hibernate根據底層數據庫的序列生成標識符,這要求底層數據庫支持序列。

          hilo

          適用于代理主鍵。Hibernate分局high/low算法生成標識符。

          seqhilo

          適用于代理主鍵。使用一個高/低位算法來高效的生成longshort或者int類型的標識符。

          native

          適用于代理主鍵。根據底層數據庫對自動生成標識符的方式,自動選擇identitysequencehilo

          uuid.hex

          適用于代理主鍵。Hibernate采用128位的UUID算法生成標識符。

          uuid.string

          適用于代理主鍵。UUID被編碼成一個16字符長的字符串。

          assigned

          適用于自然主鍵。由Java應用程序負責生成標識符。

          foreign

          適用于代理主鍵。使用另外一個相關聯的對象的標識符。

          2.5? Hibernate映射類型

          在對象/關系映射文件中,Hibernate采用映射類型作為Java類型和SQL類型的橋梁。Hibernate映射類型分為2種:內置映射類型和自定義映射類型。

          1? 內置映射類型

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

          4.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.UserTypenet.sf.hibernate.CompositeUserType接口。具體的創建自定義映射類型的方法請參考hibernate官方文檔或相關資料,這里不再詳細介紹。


          3.1? 一對一映射

          Hibernate中,持久化對象間的一對一關聯是通過one-to-one元素定義的。其定義方式如下所示。

          <one-to-one
          ??????? name="propertyName"
          ??????? class="ClassName"
          ??????? cascade="all|none|save-update|delete"
          ??????? constrained="true|false"????????????????? ?????????
          ??????? outer-join="true|false|auto"????????????? ?????????
          ??????? property-ref="propertyNameFromAssociatedClass" ??
          ??????? access="field|property|ClassName"??????????????? ?
          />

          在這段代碼中,name是指屬性的名字,class指的是被關聯的類的名字。cascade是可選項,表明操作是否從父對象級聯到被關聯的對象。constrained表明該類對應的表對應的數據庫表,和被關聯的對象所對應的數據庫表之間,通過一個外鍵引用對主鍵進行約束。

          outer-join也是可選項,它指的是當設置hibernate.use_outer_join的時候,對這個關聯允許外連接抓取。property-ref指定關聯類的一個屬性,這個屬性將會和本外鍵相對應。如果沒有指定,會使用對方關聯類的主鍵。accessHibernate用來訪問屬性的策略。

          一對一關聯有兩種不同的形式,即主鍵關聯和唯一外鍵關聯:

          1? 主鍵關聯

          主鍵關聯不需要額外的表字段。如下所示的代碼,將StudentPerson表的主鍵進行一對一關聯:

          <one-to-one name="person" class="Person"/>

          <one-to-one name="student" class="Student" constrained="true"/>

          PersonStudent兩個表中相關字段是對等的。在下面的代碼中,Person表的主鍵將采用foreign的方式生成。

          <class name="Person" table=" Person ">
          ??? <id name="id" column=" Person _ID">
          ??????? <generator class="foreign">
          ??????????? <param name="property">employee</param>
          ??????? </generator>
          ??? </id>
          ??? ...
          ??? <one-to-one name="Student"
          ??????? class="Student"
          ??????? constrained="true"/>
          </class>

          2? 惟一外鍵關聯

          此種關聯方式是指一個外鍵與一個惟一的關鍵字相關聯,上面的StudentPerson的例子,如果使這種關聯方式,應該表達成:

          <many-to-one name=" Person " class="Person" column=" Person _ID" unique="true"/>

          3.2? 多對一映射

          持久化對象間的多對一關聯是通過many-to-one元素定義的。其定義方式如下所示。

          <many-to-one
          ??????? name="propertyName"
          ??????? column="column_name"
          ??????? class="ClassName"
          ??????? cascade="all|none|save-update|delete"
          ??????? outer-join="true|false|auto"
          ??????? update="true|false"
          ??????? insert="true|false"
          ??????? property-ref="propertyNameFromAssociatedClass"
          ??????? access="field|property|ClassName"
          />

          在這段代碼中,name指類的屬性名,column指表的字段名,class是可選項,指關聯的類的名字。cascade指明哪些操作會從父對象級聯到關聯的對象,outer-join指的是當設置hibernate.use_outer_join的時候,對這個關聯允許外連接抓取。update用于指定對應的字段是否用于UPDATEproperty-ref用于指定關聯類的一個屬性,這個屬性將會和本外鍵相對應,access為可選項,指訪問屬性的策略。

          4.4 Hibernate的檢索方式

          Hibernate的檢索方式主要有HQLQBCQBE檢索等幾種方式。Hibernate查詢語言(Hibernate Query Language,簡稱HQL)是一種面向對象的查詢語言。HQL功能強大且簡單易學,它具有以下功能。

          • 在查詢語句中設定各種查詢條件。
          • ?支持投影查詢,即僅檢索出對象的部分屬性。
          • ?支持分頁查詢。
          • ?支持連接查詢。
          • ?支持分組查詢,允許使用havinggroup by關鍵字。
          • ?提供內置聚集函數,如sum()min()max()等。
          • ?能夠調用用戶自定義的SQL函數。
          • ?支持子查詢,即嵌入式查詢。
          • ?支持動態綁定參數。

          Session接口的find()方法及Query接口都支持HQL檢索方式。如下代碼是一個使用Query接口查詢的示例。

          //創建一個Query對象
          Query query = session.createQuery ( “form User as u where u.name=:userName” + “ and u.age=:userAge” ) ;
          ?
          //動態綁定參數
          query.setString( “userName” , “Bush” );
          query.setString( “userAge” , “50” );
          ?
          //執行查詢語句,返回查詢結果X
          List results = query.list();

          Query By CriteriaQBC)和Query By ExampleQBE)提供了檢索對象的其他方式,這些檢索方式主要由Criteria接口、Criterion接口、Expression類和Example類組成,支持在運行時動態生成查詢語句。關于QBCQBE的內容可以參考Hibernate官方文檔或相關書籍,這里不再詳細介紹。

          posted on 2007-03-31 22:00 天外飛仙 閱讀(536) 評論(2)  編輯  收藏 所屬分類: hibernate

          Feedback

          # QQ炫舞 2009-09-03 20:28 蔣龍
          jnfds   回復  更多評論
            

          # QQ炫舞 2009-09-03 20:28 蔣龍
          好  回復  更多評論
            

          主站蜘蛛池模板: 通辽市| 云和县| 石台县| 菏泽市| 连州市| 湖北省| 安庆市| 华蓥市| 扶沟县| 乐亭县| 临颍县| 贡觉县| 垣曲县| 富宁县| 彭水| 湖南省| 隆回县| 得荣县| 望城县| 横峰县| 桂林市| 南雄市| 嘉兴市| 肇源县| 孟村| 九龙城区| 广平县| 米脂县| 琼海市| 冀州市| 林西县| 南丹县| 顺平县| 岗巴县| 浙江省| 兴安县| 拉孜县| 突泉县| 庆安县| 利川市| 凤冈县|