hibernate--持久對象的生命週期介紹

持久化對象的狀態

html

一、 瞬時對象(Transient Object):使用new操做符初始化的對象不是馬上就持久的。它們的狀態是瞬時的,也就是說它們沒有任何跟數據庫表相關聯的行爲,只要應用再也不引用這些對象(再也不被任何其它對象所引用),它們的狀態將會丟失,並由垃圾回收機制回收java

二、 持久化對象(Persistent Object):持久實例是任何具備數據庫標識的實例,它有持久化管理器Session統一管理,持久實例是在事務中進行操做的----它們的狀態在事務結束時同數據庫進行同步。當事務提交時,經過執行SQL的INSERT、UPDATE和DELETE語句把內存中的狀態同步到數據庫中。數據庫

三、 遊離(離線)對象(Detached Object):Session關閉以後,持久化對象就變爲離線對象。離線表示這個對象不能再與數據庫保持同步,它們再也不受hibernate管理。緩存

Transient對象:隨時可能被垃圾回收器回收(在數據庫中沒有於之對應的記錄,應爲是new初始化),而執行save()方法後,就變爲Persistent對象(持久性對象),沒有歸入session的管理安全

Persistent對象:在數據庫有存在的對應的記錄,歸入session管理。在清理緩存(髒數據檢查)的時候,會和數據庫同步。session

Detached對象:也可能被垃圾回收器回收掉(數據庫中存在對應的記錄,只是沒有任何對象引用它是指session引用),注引狀態通過Persistent狀態,沒有歸入session的管理框架

 1 package h.one.test;
 2 
 3 import h.one.bean.User;
 4 import h.one.utils.HibernateUtil;
 5 
 6 import java.util.Date;
 7 
 8 import org.hibernate.HibernateException;
 9 import org.hibernate.Session;
10 import org.hibernate.Transaction;
11 import org.junit.Test;
12 
13 public class testSave1 {
14 
15     @Test
16     public void testSave1() {
17         Session session = null;
18         Transaction tx = null;
19         User user = null;
20 
21         try {
22             session = HibernateUtil.getSession();
23             tx = session.beginTransaction();
24 
25             // Transient狀態
26             user = new User();
27             user.setName("李四");
28             user.setPassword("123");
29             user.setCreateTime(new Date());
30             user.setExpireTime(new Date());
31 
32             /*
33              * persistent狀態 persistent狀態的對象,當屬性發生改變的時候,hibernate會自動和數據庫同步
34              */
35             session.save(user);
36 
37             user.setName("王五");
38             // 實際上user.setName("王五")此時已經發出一條update指令了。
39             // 也能夠顯示的調用update指定
40             // session.update(user);
41 
42             tx.commit();
43         } catch (Exception e) {
44             e.printStackTrace();
45             tx.rollback();
46         } finally {
47             HibernateUtil.closeSession(session);
48         }
49 
50         /*
51          * 今後處開始session已經在上面關閉,這時user對象狀態就變爲detached狀態,
52          * 全部user對象已經不被session管理,但數據庫中確實存在與至對應的記錄(王五)。
53          */
54         // detached狀態
55         user.setName("張三");
56 
57         try {
58             session = HibernateUtil.getSession();
59             session.beginTransaction();
60             /*
61              * 此時session又對user對象進行管理 當session發出update指定後,進行更新數據爲(張三。)
62              */
63             session.update(user);
64 
65             // update後user對象狀態又變爲persistent狀態
66             session.getTransaction().commit();
67             /*
68              * 此時session提交事務,發出update語句 Hibernate: update User set name=?,
69              * password=?, createTime=?, expireTime=? where id=?
70              */
71         } catch (HibernateException e) {
72             // TODO Auto-generated catch block
73             e.printStackTrace();
74             session.getTransaction().rollback();
75         } finally {
76             HibernateUtil.closeSession(session);
77         }
78     }
79 }
View Code

Hibernate加載數據:

兩種:get()、load()ide

1、 Session.get(Class clazz,  Serializable id)方法優化

* clazz:須要加載對象的類,例如:User.classspa

* id:查詢條件(實現了序列化接口的對象):

例"4028802c46d255740146d25576320000"字符串已經實現了序列化接口。

返回值: 此方法返回類型爲Object,也就是對象,而後咱們再強行轉換爲須要加載的對象就能夠了。

若是數據不存在,則返回null;

注:執行此方法時當即發出查詢SQL語句。加載User對象

加載數據庫中存在的數據,代碼以下

 1 @Test
 2     public void testLoad() {
 3         Session session = null;
 4         Transaction tx = null;
 5 
 6         try {
 7             session = HibernateUtil.getSession();
 8             tx = session.beginTransaction();
 9 
10             /*
11              * Object org.hibernate.Session.get(Class arg0, Serializable arg1)
12              * throws HibernateException arg0:須要加載對象的類,例如:User.class
13              * arg1:查詢條件(實現了序列化接口的對象
14              * ):例"4028818a245fdd0301245fdd06380001"字符串已經實現了序列化接口。
15              * 此方法返回類型爲Object,也就是對象,而後咱們再強行轉換爲須要加載的對象就能夠了。 若是數據不存在,則返回null
16              * 執行此方法時當即發出查詢SQL語句。加載User對象。
17              */
18             User user = (User) session.get(User.class,"4028802c46d255740146d25576320000");
19 
20             // 數據加載完後的狀態爲persistent狀態。數據將與數據庫同步。
21             System.out.println("user.name=" + user.getName());
22 
23             // 由於此的user爲persistent狀態,因此數據庫進行同步爲龍哥。
24             user.setName("龍哥");
25             session.getTransaction().commit();
26         } catch (HibernateException e) {
27             e.printStackTrace();
28             session.getTransaction().rollback();
29         } finally {
30             if (session != null) {
31                 if (session.isOpen()) {
32                     session.close();
33                 }
34             }
35         }
36     }
View Code

1、 Object Session.load(Class clazz, Serializable id) throws HibernateException

* clazz:須要加載對象的類,例如:User.class

* id:查詢條件(實現了序列化接口的對象):例"4028802c46d255740146d25576320000"字符串已經實現了序列化接口。

* 此方法返回類型爲Object,但返回的是代理對象。

* 執行此方法時不會當即發出查詢SQL語句。只有在使用對象時,它才發出查詢SQL語句,加載對象。

* 由於load方法實現了lazy(稱爲延遲加載、賴加載)

* 延遲加載:只有真正使用這個對象的時候,才加載(才發出SQL語句)

* hibernate延遲加載實現原理是代理方式。

* 採用load()方法加載數據,若是數據庫中沒有相應的記錄,則會拋出異常對象不找到(org.hibernate.ObjectNotFoundException)

 1 @Test
 2     public void testLoad() {
 3         Session session = null;
 4         Transaction tx = null;
 5         try {
 6             session = HibernateUtil.getSession();
 7             tx = session.beginTransaction();
 8 
 9             User user = (User) session.load(User.class,
10                     "4028802c46d255740146d25576320000");
11 
12             // 只有在使用對象時,它才發出查詢SQL語句,加載對象。
13             System.out.println("user.name=" + user.getName());
14 
15             // 由於此的user爲persistent狀態,因此數據庫進行同步爲龍哥。
16             user.setName("發哥");
17 
18             session.getTransaction().commit();
19         } catch (HibernateException e) {
20             e.printStackTrace();
21             session.getTransaction().rollback();
22         } finally {
23             if (session != null) {
24                 if (session.isOpen()) {
25                     session.close();
26                 }
27             }
28         }
29     }
View Code

Hbernate兩種加載數據方式的區別:

get()方法默認不支持lazy(延遲加載)功能,而load支持延遲加載

get()方法在查詢不到數據時,返回null,而load由於支持延遲加載,只有在使用對象時才加載,因此若是數據庫中不在數據load會拋出異常(org.hibernate.ObjectNotFoundException)。

get()和load()只根據主鍵查詢,不能根據其它字段查詢,若是想根據非主鍵查詢,可使用HQL

hibernate更新數據:

創建使用hibernate進行更新數據時,先加載數據,而後再修改後更新。

不然一些字段能夠會被null替換。

 1 @Test
 2     public void testDelete() {
 3         Session session = null;
 4         Transaction tx = null;
 5 
 6         try {
 7             session = HibernateUtil.getSession();
 8             tx = session.beginTransaction();
 9 
10             User user = (User) session.load(User.class,
11                     "4028802c46d255740146d25576320000");
12             session.delete(user);
13 
14             session.getTransaction().commit();
15         } catch (HibernateException e) {
16             e.printStackTrace();
17             session.getTransaction().rollback();
18         } finally {
19             if (session != null) {
20                 if (session.isOpen()) {
21                     session.close();
22                 }
23             }
24         }
25         // transistent狀態(數據庫中沒有配區的數據記錄。)
26     }
View Code

query接口初步

Query session.createQuery(String hql)方法;

* hibernate的session.createQuery()方法是使用HQL(hibernate的查詢語句)語句查詢對象的。

* hql:是查詢對象的,例如:"from User",其中from不區分大小寫,而User是區分大小寫,由於它是對象。是User類

* 返回Query對象。

* 執行這條語句後,Hibernate會根據配置文件中所配置的數據庫適配器自動生成相應數據庫的SQL語句。如:

ibernate: select user0_.id as id0_, user0_.name as name0_, user0_.password as password0_, 
user0_.createTime as createTime0_, user0_.expireTime as expireTime0_ from User user0_
View Code
Query的分頁查詢:
 1 @Test
 2     public void testQuery1() {
 3         Session session = null;
 4         try {
 5             session = HibernateUtil.getSession();
 6             session.beginTransaction();
 7             Query query = session.createQuery("from User");
 8             // 分頁查詢
 9             query.setFirstResult(0);// 從哪一條記錄開始查詢,是從0開始計算
10             query.setMaxResults(2);// 分頁每頁顯示多少條記錄。
11             /*
12              * Query對象中有一個list()方式,將全部查詢來的對象自動生成list對象返回。
13              */
14             List userList = query.list();
15             // 而後咱們就能夠顯示數據了。
16             for (Iterator iter = userList.iterator(); iter.hasNext();) {
17                 User user = (User) iter.next();
18                 System.out.print(user.getId() + "   ");
19                 System.out.println(user.getName());
20             }
21             session.getTransaction().commit();
22         } catch (HibernateException e) {
23             e.printStackTrace();
24             session.getTransaction().rollback();
25         } finally {
26             HibernateUtil.closeSession(session);
27         }
28     }
View Code

總結:

Hibernate是一個O/R映射框架(也稱爲ORM)

從ORM詞來看,O---Object(對象模型);R--- Relational(關聯模型),能夠作對象和關聯的一種映射,固然這只是部分功能,一個完善ORM框架應該具備更多的功能:如HQL相關的查詢語句、提供緩存機制(一級緩存、二級緩存)。

Java開發數據庫時,使用JDBC,可是須要編寫大量相同的代碼,這樣不便提升生產效率,而hibernate可讓你不能編寫大量的相同的代碼。從而提升生產效率。另外一方面,hibernate可讓咱們更面對象化開發,還有一個移植性hibernate只須要更改配置文件(數據庫適配器)的選項,就能夠很是方便的移植到不一樣的數據庫,而不須要從新編寫不一樣數據庫廠家所對應的JDBC、SQL語句了。還有hibernate能夠解決阻抗不匹配(Java類中有繼承關係,而關係型數據庫中沒有這個功能(目前數據庫還不是面向對象,都是關係型數據庫)),使用hibernate框架,侵入性比較好(所以hibernate稱爲輕量級框架)

O/R映射框架和使用環境:在程序中添加→修改→保存;查詢能夠批量,可是修改不可爲批量性;程序中有大量的數據只讀,這樣就能夠一次性讀取到緩存中;對象間存在天然的關係;不須要數據庫SQL特定的語句優化。

O/R映射框架不適合環境:彙集性操做:批量性添加、修改。批量的統計查詢。

Configuration對象:讀取hibernate配置文件(hibernate.cfg.xml或hiberante.properties)的. new Configuration()默認是讀取hibernate.properties, 因此使用new Configuration().configure();來讀取hibernate.cfg.xml配置文件

SessionFactory:是一個重量級對象,它的建立是耗時的。由於它對應一個數據庫裏全部配置,包括一些緩存機制都由SessionFactory來維護,它與二級緩存是綁定的。一般只建立一次,但它是線程安全的。

Session:是非線程安全的,它是經過SessionFactory來建立的。不要多個線程同時訪問同一個Session,不然會出現一些未知問題。一般是一個請求對應一個Session,請求完成要關閉Session

Transaction:hibernate默認不是自動開啓事務的,因此要手動開啓事務、手動提交事務、手動回滾事務、手動關閉事務。固然能夠經過配置文件配置成自動。通常使用手動。

Hibernate正常的開發思路:考慮對象模型這一塊,把對象模型創建起來,把對象圖創建起來,對象之間的關係創建起來、而後再編寫映射文件(hbm),而後根據映射文件生成數據庫表。數據庫對我來講是透明的,咱們只操做對象不用關心數據庫。

——————————————————————————————————————————————————————————————————————————————

原文連接:http://www.cnblogs.com/sunhan/p/3808680.html

相關文章
相關標籤/搜索