Hibernate對象的CRUD操作,hibernate對象crud
1. Hibernate對象的CRUD操作1.1. 對象的三種狀態
瞬時(Transient) - 由new操作符建立,且尚未與HibernateSession 關聯的對象被認定為瞬時(Transient)的。瞬時(Transient)對象不會被持久化到資料庫中,也不會被賦予持久化標識(identifier)。如果瞬時(Transient)對象在程式中沒有被引用,它會被記憶體回收行程(garbage collector)銷毀。使用Hibernate Session可以將其變為持久(Persistent)狀態。(Hibernate會自動執行必要的SQL語句)
持久(Persistent) - 持久(Persistent)的執行個體在資料庫中有對應的記錄,並擁有一個持久化標識(identifier)。持久(Persistent)的執行個體可能是剛被儲存的,或剛被載入的,無論哪一種,按定義,它存在於相關聯的Session作用範圍內。 Hibernate會檢測到處於持久(Persistent)狀態的對象的任何改動,在當前操作單元(unit of work)執行完畢時將對象資料(state)與資料庫同步(synchronize)。開發人員不需要手動執行UPDATE。將對象從持久(Persistent)狀態變成瞬時(Transient)狀態同樣也不需要手動執行DELETE語句。
脫管(Detached) – 與持久(Persistent)對象關聯的Session被關閉後,對象就變為脫管(Detached)的。 對脫管(Detached)對象的引用依然有效,對象可繼續被修改。脫管(Detached)對象如果重新關聯到某個新的Session上,會再次轉變為持久(Persistent)的(在Detached其間的改動將被持久化到資料庫)。這個功能使得一種編程模型,即中間會給使用者考慮時間(user think-time)的長時間啟動並執行操作單元(unit of work)的編程模型成為可能。我們稱之為應用程式事務,即從使用者觀點看是一個操作單元(unit of work)。
|
// 讀取設定檔,得到Configuration對象
Configuration config = new Configuration().configure();
// 獲得會話工廠
SessionFactory sf = config.buildSessionFactory();
Session session = sf.openSession();
sf.getCurrentSession();
// session.
Transaction tx = null;
try {
// 開始事務
tx = session.beginTransaction();
UserModel userModel =new UserModel("003","morris", 22);
// 此時userModel為瞬時態
// 儲存對象
session.save(userModel);
// 此時userModel持久態
// 提交事務
tx.commit();
} catch (Exceptione) {
e.printStackTrace();
if (tx !=null) {
tx.rollback();
}
} finally {
session.close();
}
// 此時userModel脫管態 |
1.2. 增加持久對象
Ø persist() 使一個臨時執行個體持久化。然而,它不保證立即把標識符值分配給持久性執行個體,這會發生在flush的時候。persist() 也保證它在事務邊界外調用時不會執行 INSERT 語句。這對於長期啟動並執行帶有擴充會話/持久化內容相關的會話是很有用的。
Ø save() 保證返回一個標識符。如果需要運行 INSERT 來擷取標識符(如 "identity" 而非"sequence" 產生器),這個 INSERT 將立即執行,不管你是否在事務內部還是外部。這對於長期啟動並執行帶有擴充會話/持久化內容相關的會話來說會出現問題。
1.3. 刪除持久對象
Ø delete() 用來刪除一個對象,參數為一個對象,並不是一個主鍵,執行delete方法的時候首先會去資料庫中尋找有有沒有對象的主鍵所對應的記錄,如果有就會執行刪除操作;
如果沒有,不會報錯。
|
Hibernate: select usermodel_.userId, usermodel_.userName as userName2_0_, usermodel_.userAge as userAge3_0_ from userInfo usermodel_ where usermodel_.userId=?
Hibernate: delete from userInfo where userId=? |
1.4. 修改持久對象
Ø update
|
Hibernate: update userInfo set userName=?, userAge=? where userId=? |
Ø merger
l 如果資料庫中的資料與對象的資料一致,執行下面的sql語句
|
Hibernate: select usermodel0_.userId as userId1_0_0_, usermodel0_.userName as userName2_0_0_, usermodel0_.userAge as userAge3_0_0_ from userInfo usermodel0_ where usermodel0_.userId=? |
l 如果資料庫的資料與對象的資料不一致,就會執行下面的sql語句
|
Hibernate: select usermodel0_.userId as userId1_0_0_, usermodel0_.userName as userName2_0_0_, usermodel0_.userAge as userAge3_0_0_ from userInfo usermodel0_ where usermodel0_.userId=?
Hibernate: update userInfo set userName=?, userAge=? where userId=? |
l 如果資料庫中不存在這條記錄,則添加
|
Hibernate: select usermodel0_.userId as userId1_0_0_, usermodel0_.userName as userName2_0_0_, usermodel0_.userAge as userAge3_0_0_ from userInfo usermodel0_ where usermodel0_.userId=?
Hibernate: insert into userInfo (userName, userAge, userId) values (?, ?, ?) |
1) 如果session中存在相同持久化標識的執行個體,用使用者給出的對象的狀態覆蓋舊有的持久執行個體
2) 如果session中沒有相應的持久執行個體,則嘗試從資料庫中載入,或建立新的持久化執行個體
3) 最後返回該持久執行個體
4) 使用者給出的這個對象沒有被關聯到 session 上,它依舊是脫管的
Ø saveOrUpdate 自動檢測,如果是新的記錄就添加,如果是修改記錄,就修改
1) 如果對象已經在本session中持久化了,不做任何事
2) 如果另一個與本session關聯的對象擁有相同的持久化標識,拋出一個異常
3) 如果對象沒有持久化識別屬性,對其調用save()
4) 如果對象的持久標識表明其是一個新執行個體化的對象,對其調用save()。
1.4.1. update和merge方法的區別
1) 如果資料庫裡面存在你要修改的記錄,update每次是直接執行修改語句;而merge是先在緩衝中尋找,緩衝中沒有相應資料,就到資料庫去查詢,然後再合并資料,如果資料是一樣的,那麼merge方法不會去做修改,如果資料有不一樣的地方,merge才真正修改資料庫。
2) 如果資料庫中不存在你要修改的記錄,update是報錯;而merge方法是當作一條新增的值,向資料庫中新增一條資料。
3) update後,傳入的TO對象就是PO的了,而merge還是TO的。
4) 如果你確定當前session沒有包含與之具有相同持久化標識的持久執行個體,使用update()。如果想隨時合并改動而不考慮session的狀態,使用 merge()。換句話說,在一個新 session中通常第一個調用的是update()方法,以保證重新關聯脫管對象的操作首先被執行。
5) 請注意:使用update來把一個TO變成PO,那麼不管是否修改了對象,都是要執行update sql語句的。
1.4.2. 使用update() 或saveOrUpdate()的情境
1) 程式在第一個 session 中載入對象
2) 該對象被傳遞到表現層
3) 對象發生了一些改動
4) 該對象被返回到商務邏輯層
5) 程式調用第二個session的update()方法持久這些改動
1.5. 按主鍵查詢持久對象
1) load方法:load的時候首先查詢一級緩衝,沒有就建立並返回一個代理對象,等到使用的時候,才查二級緩衝,如果二級緩衝中沒有資料就查資料庫,如果資料庫中沒有,就拋例外
2) get方法:先查緩衝,如果緩衝中沒有這條具體的資料,就查資料庫,如果資料庫沒有值,就返回null,總之get方法不管用不用,都要拿到真實的資料
1.5.1. get和load的區別
1) get()方法直接返回實體類,如果查不到資料則返回null。load()會返回一個實體代理對象(當前這個對象可以自動轉化為實體物件),但當代理對象被調用時,如果沒有資料不存在,就會拋出個org.hibernate.ObjectNotFoundException異常
2) load先到緩衝(session緩衝/二級緩衝)中去查,如果沒有則返回一個代理對象(不馬上到DB中去找),等後面使用這個代理對象操作的時候,才到DB中查詢,這就是我們常說的 load在預設情況下支援消極式載入(lazy)
3. get先到緩衝(session緩衝/二級緩衝)中去查,如果沒有就到DB中去查(即馬上發出sql)。總之,如果你確定DB中有這個對象就用load(),不確定就用get()(這樣效率高)
hibernate提供的crud操作
使用HIbernate的好處是:無論你的資料庫是Oralce,還是Sqlservler,還是MySql的,在資料庫裡的查詢語句都有不同,但是在程式裡都會轉成Hibernate的Hql語句。這在資料庫操作上有一個與資料庫無關的統一語言。而且Hibernate可以配合Spring,Struts使用。我建議還是使用Hql的比較好。
String queryString = "select distinct (e) from RetiredEmployee as e "
+ "where e.masterPost.organization in (:organizations) " + sortInfo.toString();
Query query = session.createQuery(queryString).setParameterList("organizations", organizations);
Hibernate是通過持久層與實體類實現資料庫的CRUD操作,敘述怎使用Hibernate進行資料庫的CRUD操作????
1、使用hibernate把資料庫模型和java對象進行ORM映射,通過設定檔或者註解完成
2、程式通過hibernate提供的API進行CRUD,
C操作對應hibernate方法為save
R操作對應hibernate方法為get
U操作對應hibernate方法為update
D操作對應hibernate方法為delete