Java的Hibernate框架中的根本映照用法講授。本站提示廣大學習愛好者:(Java的Hibernate框架中的根本映照用法講授)文章只能為提供參考,不一定能成為您想要的結果。以下是Java的Hibernate框架中的根本映照用法講授正文
Hibernate停止了分類整合發明其實Hibernate分為三年夜部門:焦點對象、映照、HQL,這三年夜部門開辟進程中最常應用,前幾篇評論辯論了焦點對象及對象之間的轉換辦法,接上去評論辯論Hibernate的映照應用辦法。
Hibernate一個主要的功效就是映照,它可以或許在對象模子和關系模子之間轉換,是面向對象編程思惟倡導應用的,應用映照法式開辟人員只須要關懷對象模子中代碼的編寫。對象和關系數據庫之間的映照平日是由XML文檔來界說的。這個映照文檔被設計為易讀的,而且可以手動修正。這類映照關系我總結為下圖:
映照是經由過程XML來界說的,應用Hibernate創立的session來治理,最初由session應用JTA把更改提交到數據庫中。session可以懂得為耐久化治理器,治理耐久層中的對象,它是由sessionFactory創立的。應用Hibernate編程時起首要銜接數據庫,所以起首要去檢查xml中有關數據庫銜接的設置裝備擺設,依據文檔的設置裝備擺設創立sessionFactory(可以懂得為數據庫鏡像),再由sessionFactory創立一個session,最初由session同一將更改提交到數據庫,這才完成了一部一切的操作。
應用進程
1.創立映照文件,映照文件以.hbm.xml為後綴名,標明它是Hibernate的映照文件;
2.在映照文件中注冊實體類,並將實體類的屬性添加到映照類中,在添加屬性時要指定兩種值分離是id和property,id指明它是一個實體的獨一標示,property指明它是表的字段列;
3.提交修正,同步數據。
Note:開辟過xml數據轉到數據庫的開辟人員很快就可以懂得這類映照實際上是一種批量更新、批量創立的進程,映照也不破例,Hibernate劃定了一套映照尺度,依照尺度就可以夠完成轉換,它的外部完成照樣逝世的,所以它只是絕對的靈巧易用。
一個簡略的實體類映照進程:
1. 實體類User1的屬性代碼:
package com.hibernate; import java.util.Date; public class User1 { private String id; private String name; private String password; private Date createTime; private Date expireTime; public String getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getExpireTime() { return expireTime; } public void setExpireTime(Date expireTime) { this.expireTime = expireTime; } }
2. User1.java的映照文件User1.hbm.xml的外部代碼完成:
基本數據庫中可以或許設置的在Hibernate中異樣供給了設置的辦法,可使用標簽屬性來設置詳細的映照關系。
類-->表應用class標簽,經常使用屬性:
(1)name:映照實體類,它的值須要設置為須要轉化成表的實體類的稱號,在同步時會依據該屬性查找響應的實體類。
(2)table:映照數據庫表的稱號,假如要映照的表的稱號和實體類稱號不雷同,應用該屬性來指定映照的表,假如不存在的話會依據該屬性值創立一個表。
檢查上圖中設置裝備擺設生成的表構造,以下圖:
個中的表名更改成了t_user1;id字段改名為user_id,字段長度為32位;createTime屬性,映照為數據庫字段create_time,並修正為date類型。
屬性-->字段應用id或property標簽,經常使用屬性:
(1)name:功效相似於class標簽的name,值定實體類的映照屬性名;
(2)column:相似於實體類class標簽的table,指定映照表的列稱號,假如不存在將會創立;
(3)type:指定映照到數據庫中字段的數據類型,依據須要檢查文檔便可;
(4)generator,它是可選的,用來為一個耐久類生成獨一的標識。
<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供給了許多內置的完成。上面引見經常使用的幾種:
(1)identity:前往的標識符是long, short 或許int類型的。相似於數據庫的自增字段。
(2)sequence:在DB2,PostgreSQL, Oracle, SAP DB, McKoi中應用序列(sequence), 而在Interbase中應用生成器(generator)。前往的標識符是long, short或許 int類型的。在全部數據庫中自增,而不是單個的表中自增,須要指訂單個的表中自增須要添加屬性。
(3)uuid:用一個128-bit的UUID算法生成字符串類型的標識符, 這在一個收集中是獨一的(應用了IP地址)。UUID被編碼為一個32位16進制數字的字符串。相似於.NET生成的序列號。
(4)native:依據底層數據庫的才能選擇identity, sequence 或許hilo中的一個。靈巧的方法,會依據應用的數據庫來肯定應用的標識類型,MySQL會選擇identity,Oracle選擇sequence。
(5)assigned:手動為實體類制訂一個標識id。這是 <generator>元素沒有指准時的默許生成戰略。
(6)foreign:應用別的一個相干聯的對象的標識符。平日和<one-to-one>結合起來應用。
開辟人員常常習氣了手動設置裝備擺設的辦法依據文檔的解釋來編寫設置裝備擺設屬性,如許做很原始,初學者建議采取手動設置裝備擺設的辦法,有助於思慮。別的還有許多第三方對象,經由過程可視化的辦法來設置裝備擺設然後生成xml設置裝備擺設文檔,進步了開辟效力,相似的對象如:XDoclet、Middlegen和AndorMDA。
聯系關系映照之多對一
下面評論辯論了Hibernate的根本映照,一個實體類對應著一張表,在響應的Hibernate Mapping文件中應用<class>標簽映照。而且實體類中的通俗屬性對應著表字段,應用<property>標簽映照。別的在結構實體類時應留意:在實體類中應完成無參的默許的結構函數,供給一個標示,建議不要應用final潤飾實體類,為實體類生成getter和setter辦法,最初引見了幾種重要的主鍵生成戰略,接上去評論辯論多對一映照。
這類多對一聯系關系映照反響到對象模子中它是一種聚合關系,User是group的一部門,group中存在User,它們兩個的性命周期是不雷同的,可反響為下圖:
那末這類多對一關系映照在Hibernate中是若何設置的呢?上面將會引見兩種辦法,應用<many-to-one>標簽直接映照,或許應用<many-to-one>的cascade級聯修正表。
1、Many-to-one直接映照
從字面意思上就可以夠懂得,它是指多對一的關系,many指的是多的一端,one指的是少的一端,在應用時常常在多的一真個hbm中應用該標簽,並將<many-to-one>的name屬性設置為該映照文件對應的類中的one一真個屬性,如:<many-to-one name="group" column="groupid"></many-to-one>,該標簽添加在了User.hbm.xml中,它對應many;標簽中的name值為group對映照one,而且在User.java中會有一個名為group的屬性。接上去看下詳細完成完成的代碼類。
(1)User.java類代碼,個中有一個名為group的屬性,它將會作為<many-to-one>的one一真個name值。
public class User { private String name; public String GetName(){ return name; } public void SetName(String name){ this.name=name; } private Group group; public Group GetGroup(){ return group; } public void SetGroup(Group group){ this.group=group; } }
(2)User.hbm.xml中的<many-to-one>,name的值為User.java中one真個屬性值,它會在數據庫中生成一個新列,可以將該新列懂得為User表的外鍵。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2014-5-14 23:39:25 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.hibernate.User" table="USER"> <id name="id" type="java.lang.Long"> <column name="ID" /> <generator class="assigned" /> </id> <!-- name的值group為User.java中的一個對應的one中的一個屬性,它會主動在表中生成一列,所以應用column對列停止了重定名 --> <many-to-one name="group" column="groupid"></many-to-one> </class> </hibernate-mapping>
(3)測試下面的映照關系,向表中寫入兩個User對象分離為user1和user2,定名為張三和李四,應用session保留對象,向數據庫中寫入數據,代碼以下:
public void testSave1(){ Session session=null; try{ session=GetSession.getSession(); session.beginTransaction(); Group group=new Group(); group.SetName("動力節點"); User user1=new User(); user1.SetName("張三"); user1.SetGroup(group); User user2=new User(); user2.SetName("李四"); user2.SetGroup(group); session.save(user1); session.save(user2); //會報TransientObjectException毛病 //在清算緩存時產生毛病TransientObjectException //由於Group為Transient狀況,沒有被Session,在數據庫中沒有婚配的數據 //而User為Persistent狀況,在清算緩存時Hibernate在緩存中沒法找到Group對象 //揭穿:Persistent狀況的對象不克不及援用Transient狀況的對象 //該成績在testSave2辦法中更改 session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); session.getTransaction().rollback(); }finally{ GetSession.CloseSession(session); } }
然則應用下面的代碼在履行寫入時會報錯TransientObjectException,這是由於在保留User對象時它會依照<many-to-one>中添加的group去內存中查找group對象,然則下面的代碼中group對象一向都是在Transient狀況中,並沒有被session治理,也就是說查找不到session對象,而User對象進入了Persistent狀況,因而會報此毛病。准確的代碼以下:
public void testSave2(){ Session session=null; try{ session=GetSession.getSession(); session.beginTransaction(); Group group=new Group(); group.SetName("動力節點"); session.save(group); //此處將group對象設置為Persistent對象 User user1=new User(); user1.SetName("張三"); user1.SetGroup(group); User user2=new User(); user2.SetName("李四"); user2.SetGroup(group); session.save(user1); session.save(user2); //可以准確的保留數據 //由於Group和User都是Persistent狀況的對象 //所以在Hibernate清算緩存時在session中可以找到聯系關系對象 session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); session.getTransaction().rollback(); }finally{ GetSession.CloseSession(session); } }
2、級聯映照
除下面所說的將group對象和user對象都轉化到Persistent對象外,還可使用cascade級聯映照屬性,在<many-to-one>屬性中添加cascade屬性,並復制為save-update,在group對象並不是為Persistent狀況時便可寫入數據庫。如許只須要將兩個user對象的Group屬性設置為統一個group對象便可完成多對一的映照關系,此時User.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"> <!-- Generated 2014-5-14 23:39:25 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.hibernate.User" table="USER"> <id name="id" type="java.lang.Long"> <column name="ID" /> <generator class="assigned" /> </id> <!-- 級聯修正表 --> <many-to-one name="group" column="groupid" cascade="save-update"></many-to-one> </class> </hibernate-mapping>
Note:cascade設置為save-update後便可完成向數據庫中級聯修正、添加和刪除,然則詳細的級聯查詢操作卻弗成以。
對應的測試設置裝備擺設文件的辦法為以下代碼:
//級聯cascade public void testSave3(){ Session session=null; try{ session=GetSession.getSession(); session.beginTransaction(); Group group=new Group(); group.SetName("動力節點"); User user1=new User(); user1.SetName("張三"); user1.SetGroup(group); User user2=new User(); user2.SetName("李四"); user2.SetGroup(group); session.save(user1); session.save(user2); //沒有拋出TransientObjectException異常 //由於應用了級聯 //Hibernate會起首保留User的聯系關系對象Group //Group和User就都是Persistent狀況的對象了 session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); session.getTransaction().rollback(); }finally{ GetSession.CloseSession(session); } }
3、比較升華
兩種辦法異樣完成了多對一的映照辦法,成果上是雷同的,但在完成上很不雷同。不管是第一種照樣第二種采取的都是<many-to-one>在many一真個映照文件中添加該標簽,並將標簽的name屬性賦值為該映照文件注冊的類中的one一真個屬性值,如許就完成了多對一的根本映照,這是雷同點。分歧點是直接映照關系沒有采取Hibernate字段的屬性,如許在完成上較靈巧,不只支撐增刪改,並且可以查詢;第二種的cascade級聯修正則采取了Hibernate供給的辦法,此種辦法只支撐增刪改,其實不支撐查詢。