Hibernate API基礎篇 (轉載)

上面的這個圖是Hiberante應用程序的結構,
對上圖中各項的說明如下:(1)Application:應用 (2)Persistent Object:持久化對象(3)hibernate.properties:Hibernate屬性文件/Hibernate配置文件 (4)XML Mapping:Hibernate映射文件 (5)Database:數據庫
由上圖可以看出,Hibernate是通過一系列的配置文件和數據庫來實現持久化對象的持久化操作的。
為了使用Hibernate,需要創建與數據庫中的表對應的持久化對象,然后再通過影射文件將持久化對象中的屬性與數據庫表中的字段對應起來。這樣才能通過持久化對象完成對數據庫表中的數據的增加、修改、查詢和刪除操作。
Hibernate主要包括三個組件:
(1)連接管理組件:它提供了高效的數據庫連接管理。數據庫連接是和數據庫進行交互的唯一渠道,建立和關閉一個連接需要耗費大量的資源。所以現在的應用程序都采用連接池的方法來管理與數據庫的連接,避免頻繁的建立和關閉數據庫連接
(2)事務管理組件:通過事務,一次可以執行多個SQL語句,而且能夠保證這些語句執行成功或者都不成功
(3)對象/關系映射組建:對象/映射技術可以實現從對象模型到數據庫中關系模型的映射工作。通過這一技術,Hibernate實現了對象的持久化操作。
Hinernate的體系結構(運行時)
由于Hibernate非常靈活,而且提供了多種運行時的結構組成方案,這里介紹的時一個“最全面”的體系結構,它最大程度的完成了對持久層功能的封裝,也就使得在開發中要完成的工作量最少,是在開發中最經常使用的一種方式。這種方式把JDBC/JTA都交由Hibernate去完成,而不需要對這一部分進行任何處。


各個部分的主要功能如下
SessionFactory:它保存了對當前數據庫配置的所有映射關系,它是將某個數據庫的映射關系經過編譯之后全部保存在內存中的。 它還是生成Session的工廠,它在進行實例化的過程中將會用到ConnectionProvider。一個SessionFactory對應一個數據庫連接,當數據庫連接改變時需要修改SessionFactory
Sesion:是進行持久化操作的基礎,所有的持久化操作都是在Session的基礎上進行的。它相當與JDBC中的Connection。它是Hibernate的持久化管理器的核心,提供了一系列的持久化操作方法。另外,它還持有一個針對持久化對象的一級緩存,在遍歷持久化對象或者根據持久化標識查找對象的時候會用到。
Transation:功能上和數據庫中的事務完全一樣,通過它實現對數據庫中事務的控制。Transation對象是Session對象產生的,所以他的生命周期比Session短。一個Session的生命周期中可以有多個Transaction對象。
ConnectonProvider:主要作用是生成與數據庫建立了連接的JDBC對象,同時他還作為數據庫連接的緩沖池。通過ConnectionProvider實現了應用程序和底層的DataSource和DriverManager的隔離。
TransactionFactory:是生成Transaction對象的工廠,通過TransactionFactory實現了事務的封裝,使其具體的實現方法與應用程序無關。
Hibernate對象的生命周期
一共有三種生命周期:
(1)瞬態:表示該實體對象在內存中是自由存在的,也就是說與數據庫中的數據沒有任何的關聯。即,該實體從未與任何持久化上下文聯系過,沒有持久化標識(相當與主鍵)。瞬態實體的特征有:
與數據庫中的記錄沒有任何關聯,也就是沒有與其相關聯的數據庫記錄
與Session沒有任何關系,也就是沒有通過Session對象的實例對其進行任何持久化的操作。
(2)持久態:指該實體對象處于Hibernate框架所管理的狀態,也就是說這個實體對象是與Session對象的實例相關的。處于持久態的實體對象的最大特征是對其所作的任何變更操作都將被Hibernate持久化到數據庫中。處于持久態的對象具有的特征為:
每個持久態對象都于一個Session對象關聯
處于持久態的對象是于數據庫中的記錄相關聯的
Hibernate會根據持久態對象的屬性的變化而改變數據庫中的相應記錄
(3)游離態:處于持久態的實體對象,當他不再與Session對象關聯時,這個對象就變成了游離態。。游離態對象的特征有:
游離態對象一定是由持久態對象轉換而來
游離態實體不再于Session關聯
游離態實體對象與數據庫中的數據沒有直接聯系,主要表現在對其進行的修改不再影響到數據庫中的數據
游離態實體對象在數據庫中有相應的數據記錄(如果該記錄沒有被刪除)
判斷一個實體對象是否處于瞬態:
該實體對象的<id>屬性(如果存在)的值為空
如果在映射文件中為<id>設置了unsaved-value屬性,并且實體對象的id屬性的值與unsaved-value屬性的值相同
如果這個實體對象配置version屬性,并且version屬性的值為空
在映射文件中為version屬性設置了unsaved-value屬性,并且version屬性的值與unsaved-value屬性的值相同。
如果設置了interceptor,并且interceptor的isUnsaved()方法的返回值為true
滿足上述條件的實體對象就處于瞬態,否則為游離態(前提是不處于持久態)
下面通過一段代碼來說明狀態問題:
public class LifeCycle
{
{
public static final SessionFactory sessionFactory;
static
{
sessionFactory = new Configuration().configure().buildSessionFactory();
}
public static void main(String[] args)
{
LifeCycle.lifecycle();
}
public static void lifecycle()
{
// 創建游離態實體對象User
User user = new User();
user.setName( "abc" + String.valueOf( Math.random() ) );
// 為了避免兩次運行的用戶名重復,所以增加了隨機數
user.setPassword( "def" );
// user仍然處于游離態
static
{
sessionFactory = new Configuration().configure().buildSessionFactory();
}
public static void main(String[] args)
{
LifeCycle.lifecycle();
}
public static void lifecycle()
{
// 創建游離態實體對象User
User user = new User();
user.setName( "abc" + String.valueOf( Math.random() ) );
// 為了避免兩次運行的用戶名重復,所以增加了隨機數
user.setPassword( "def" );
// user仍然處于游離態
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 此時user對象仍然是Transient狀態
session.save( user );
// 此時,user對象已經被納入了Hibernate的實體管理容器中,并轉變為Persistent狀態
System.out.println( "User 1:" + user );
// 此時的id已經有值了。
get( user.getId() );
// 但并未真正的執行數據庫的操作,所以無法得到對象的值
tx.commit();
// 事務被提交后,將向數據庫的用戶表中插入一條記錄
System.out.println( "Transaction 1 commit!" );
get( user.getId() );
// 這時可以由數據庫中得到剛才插入的user對象了。
Transaction tx2 = session.beginTransaction();
user.setPassword( "mmmmmmmmmmmmm" );
tx2.commit();
// 雖然這個事務中并沒有調用Session的save()方法來保存user對象
// 但由于user對象處于Persistent狀態,所以對user對象所做的任何修改都將被持久化到數據庫中
// 那么數據庫中的用戶密碼也應該變為了def。
System.out.println( "Transaction 2 commit!" );
session.close();
Transaction tx = session.beginTransaction();
// 此時user對象仍然是Transient狀態
session.save( user );
// 此時,user對象已經被納入了Hibernate的實體管理容器中,并轉變為Persistent狀態
System.out.println( "User 1:" + user );
// 此時的id已經有值了。
get( user.getId() );
// 但并未真正的執行數據庫的操作,所以無法得到對象的值
tx.commit();
// 事務被提交后,將向數據庫的用戶表中插入一條記錄
System.out.println( "Transaction 1 commit!" );
get( user.getId() );
// 這時可以由數據庫中得到剛才插入的user對象了。
Transaction tx2 = session.beginTransaction();
user.setPassword( "mmmmmmmmmmmmm" );
tx2.commit();
// 雖然這個事務中并沒有調用Session的save()方法來保存user對象
// 但由于user對象處于Persistent狀態,所以對user對象所做的任何修改都將被持久化到數據庫中
// 那么數據庫中的用戶密碼也應該變為了def。
System.out.println( "Transaction 2 commit!" );
session.close();
get( user.getId() );
// 此時密碼已經變為新的值了
}
public static User get( String id )
{
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = (User)session.get( User.class, id );
// Hibernate在返回User對象之間會將其納入到Hibernate的實體管理容器中
// 所以,這時的user對象是Persistent狀態的
display( user );
tx.commit();
session.close();
return user;
}
public static void display( Object obj )
{
System.out.println( obj );
}
}
// 此時密碼已經變為新的值了
}
public static User get( String id )
{
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = (User)session.get( User.class, id );
// Hibernate在返回User對象之間會將其納入到Hibernate的實體管理容器中
// 所以,這時的user對象是Persistent狀態的
display( user );
tx.commit();
session.close();
return user;
}
public static void display( Object obj )
{
System.out.println( obj );
}
}
提示1:Hibernate支持四種數據庫連接池的組件
(1)C3P0。這是Hiberante自身提供的。其文檔地址見:www.mchange.com/projects/c3p0/index.html;有關Hibernte中配置c3p0的文檔參考:www.hibernate.org/214.html
(2)DBCP:它是Apache軟件基金組織的一個開源項目。由于在Hibernte3中不再提供DBCConnectionProvider類來直接使用DBCP建立數據庫的連接池,在這里提供兩種方法解決這個問題。一種是仿照Hibernate2中的DBCPConnectionProvider類自己實現一個使用DBCP并實現了ConnetcitonProvider接口的連接池類。另一種是讓應用服務器通過JNDI的方式來提供數據庫的連接,Hibernate通過JNDI得到數據庫的連接。DBCP的詳細信息見:http://jakarta.apache.org/commons/dbcp/。關于自己實現ConnectionProvider接口的方法見http://wiki.apache.org/jakarta-commons/DBCP/Hibernate
(3)Proxool:也是開放源代碼的提供數據庫連接池的組件。其官方網站為:http://proxool.sourceforge.net。有關配置的詳細參數見官方網站
文章來源:http://www.360doc.com/content/06/1126/17/2434_273160.shtml
文章來源:http://www.360doc.com/content/06/1126/17/2434_273160.shtml
posted on 2011-07-15 11:33 七孑 閱讀(330) 評論(0) 編輯 收藏 所屬分類: SSH構架精要