hibernate有三種狀態,分別爲:
Transient(瞬時狀態),Persistent(持久化狀態),Detached(遊離狀態)
下圖展示了對象在hibernate中的狀態轉換:
例一
@Test
public void Test12() {
Configuration cfg = new Configuration().configure();//獲取配置
SessionFactory sessionFactory = cfg.buildSessionFactory();//創建會話工廠
Session session = sessionFactory.openSession();//開啓會話
Transaction transaction = session.beginTransaction();//開啓事務
Dept dept = new Dept(0, "gz", "123");//對象剛被new出來,瞬時狀態
try {
session.save(dept);//經過save方法轉換爲持久狀態
SessionDao.transaction.commit();//提交事務,轉換爲遊離狀態
}catch(Exception e) {
e.printStackTrace();
SessionDao.transaction.rollback();//事務異常則回滾
}finally{//關閉資源
session.close();
sessionFactory.close();
}
}
執行結果:
Hibernate:
insert
into
dept
(dname, loc, deptno)
values
(?, ?, ?)
可以看見hibernate提交了一條插入語句
例二:
Dept dept = new Dept(60, "gz", "123");//對象剛被new出來,瞬時狀態
try {
session.save(dept);//經過save方法轉換爲持久狀態
dept.setDname("gz1");//先比較dept是否改變,如果有,自動將dname save到持久對象中
transaction.commit();//提交事務,轉換爲遊離狀態
dept.setDname("gz2");
session.save(dept);//沒有提交,無效語句
}
執行結果:
Hibernate:
insert
into
dept
(dname, loc, deptno)
values
(?, ?, ?)
Hibernate:
update
dept
set
dname=?,
loc=?
where
deptno=?
hibernate先插入再更新gz1
可以看到無效語句並沒有被提交。
如果一個對象以及是持久化狀態了,那麼此時對該對象進行各種修改,或者調用多次update、save方法時,hibernate都不會發送sql語句,只有當事物提交的時候,此時hibernate纔會拿當前這個對象與之前保存在session中的持久化對象進行比較,如果不相同就發送一條update的sql語句,否則就不會發送update語句
例三:
Dept dept = new Dept(60, "gz", "123");//對象剛被new出來,瞬時狀態
try {
session.save(dept);//經過save方法轉換爲持久狀態
dept.setDname("gz1");
session.save(dept);
dept.setDname("gz2");
session.save(dept);
transaction.commit();//提交事務,轉換爲遊離狀態
}
這次又將提交幾條sql呢?
答案是:1(第一次save)+1(commit次數)
當session調用load、get方法時,此時如果數據庫中有該對象,則該對象也變成了一個持久化對象,被session所託管。
但是無論dept怎麼千變萬化,若dept無數據改變,session毫無反應,若有,改變的都只是session(持久化)中的dept,只有事務的commit纔會先比較再發送update sql。