一、Hibernate持久化對象三種狀態
在Hibernate中持久化類的對象可以劃分爲三種狀態,分別是瞬態,持久態,脫管態。
1. 瞬態(Transient),也叫臨時態。處於這種狀態的對象具備的特徵如下:
a) 不在Session的緩存中,不與任何的Session實例相關聯。
b) 在數據庫中沒有與之相對應的記錄。
User user = new User();
user.setName("姓名");
user.setAge("年齡");
2. 持久態(Persistent),處於這種狀態的對象具備的特徵如下:
a) 在Session的緩存中,與Session實例相關聯。
b) 在數據庫中存在與之相對應的記錄。
通過Session對象的save()方法進行保存處於瞬時態的對象後,該對象就變爲持久態。此時Session中已經存在該對象,並且對應數據庫中的一條記錄。
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("姓名");
user.setAge("年齡");
session.save(user);
tx.commit();
在調用save()方法後,持久化對象user就變爲持久態,但是執行了commit()方法之後,數據庫操作纔會進行。3. 脫管態(Detached),也叫遊離態。處於這種狀態的對象具備的特徵如下:
a) 不在Session的緩存中,不與任何的Session實例相關聯。
b) 在數據庫中存在與之相對應的記錄。(前提條件是沒有其他Session實例刪除該條記錄)。
這三種狀態之間是可以轉換的:
二、session的Get() 和 Load()區別
在Hibernate中,持久化對象的三種狀態是和Session的週期相關的,因爲Hibernate中的操作都是基於Session緩存機制完成的。所以Session對象的生命週期也關係着持久化對象的生命週期。那麼什麼是Session緩存機制呢?
Hibernate中的session緩存機制和會話session沒有一點關係,是完全不同的兩個概念。
Hibernate中引入session緩存的目的是:
1、減少訪問數據庫的頻率,可以提高數據庫訪問的性能。
2、保證緩存中的對象與數據庫中的相關記錄保持同步。
3、當緩存中的持久化對象(位於緩存中的對象)之間存在循環關聯關係時,Sessioin會保證不出現訪問對象的死循環。
session有保存、更新、刪除、查詢方法。而對於查詢可以通過get和load兩種方式來獲取數據。下面就來說一下這兩種方式的區別。
Get():
public void testGet1(){
Session session = null;
try{
session = HibernateUntils.getSession();
session.beginTransaction();
User user=(User)session.get(User.class,"402898514099b934014099b936ca0003");
System.out.println(user.getUsername());
user.setUsername("TomNew");
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUntils.closeSession(session);
}
}
設置斷點,Debug方式運行,有如下結果:
Load():
public void testLoad1() {
Session session = null;
try {
session = HibernateUntils.getSession();
session.beginTransaction();
User user = (User)session.load(User.class, "402898514099b934014099b936ca0003");
System.out.println(user.getUsername());
user.setUsername("王五");
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUntils.closeSession(session);
}
}
結果如下:
但是,此時的user並不爲空
通過對比我們可以看出:
執行get會馬上發出查詢語句。但是執行load不會馬上發出查詢語句,因爲load支持lazy(延遲加載)。只有真正使用這個對象的時候,再創建,對於hibernate來說才真正的發出查詢語句,主要是爲了提高性能。lazy是通過實現代理對象實現,代理對象主要採用的是CGLIB庫生成的,採用的是繼承方式。不同於JDK中的代理。
另外,這兩個方法的區別就是:如果查詢的數據爲空,那麼get方式返回null,而load方式會拋出ObjectNotFoundException異常