Hibernate的常用方法區別(六)
感謝Jie’ blog http://ilog.vip/ ,謝謝他讓我有了繼續寫下去的信念。願一起堅持,在路上… 上一章簡單介紹了Hibernate三種實體狀態(五),如果沒有看過,請觀看上一章 Hibernate的Session中提供了很多的方法,這些方法在某些方面是效果一樣的,但還是有一些不同的。下面,進行一些簡單的區分.
一. save()與saveOrUpdate()方法
save()方法的執行過程為:
- 系統根據指定的ID生成策略,為臨時物件生成一個唯一的OID;
- 將臨時物件載入到快取中,使之變成持久化物件;
- 提交事務時,清理快取,利用持久化物件包含的資訊生成insert語句,將持久化物件儲存到資料庫。 這個方法,主要是進行實體物件的儲存,將瞬時物件轉換成持久物件,儲存在資料庫中。
/**
* 驗證save()方法設定id的情形
*/
@Test
public void test1(){
Session session=HibernateUtil.getSession();
Transaction transaction=session.beginTransaction();
User user=new User();
user.setId(6);
user.setSex("不知道");
session.save(user);
transaction.commit();
}
設定的這個id,並不會起作用,只是將瞬時態物件轉換成遊離態物件。Hibernate 中的真實id是根據Id生成策略進行指定的。 資料庫中的接下來的id該為27.
@Test
public void test2(){
Session session=HibernateUtil.getSession();
Transaction transaction=session.beginTransaction();
User user=new User();
user.setSex("不知道");
session.saveOrUpdate(user);
transaction.commit();
}
執行的是插入的方法,呼叫insert 語句進行插入. 如果有id,並且這個id已經存在於資料庫中:
@Test
public void test2(){
Session session=HibernateUtil.getSession();
Transaction transaction=session.beginTransaction();
User user=new User();
user.setId(8); //存在為8的資料,呼叫的是update的語句,進行修改.
// user.setId(30) ;// 沒有id為30的資料。
user.setSex("不知道");
session.saveOrUpdate(user);
transaction.commit();
}
如果有id,但這個id並沒有存在於資料庫中,即這個id很大,如30的Id. 會丟擲異常。 這個時候,應該用save()方法。 如果執行的是刪除後的資料,如:
@Test
public void test2(){
Session session=HibernateUtil.getSession();
Transaction transaction=session.beginTransaction();
User user=new User();
user.setId(6);
session.delete(user);
user.setSex("知道");
session.saveOrUpdate(user);
transaction.commit();
}
那麼會執行兩條語句,一條是刪除6的資料,另外一條是insert語句,插入sex=“知道”。
二.save()與saveOrUpdate()與merge()方法。
merge()方法時,當session中已經存在了一條持久化物件,再設定一個相同的id的物件,那麼這裡用saveOrUpdate()方法會出現錯誤,丟擲異常的,應該用merge()方法。merge,中文意思為合併。
@Test
public void testMerge(){
Session session=HibernateUtil.getSession();
Transaction transaction=session.beginTransaction();
User user1=session.get(User.class,7);
User user2=new User();
user2.setId(7);
user2.setDescription("兩個相同的id");
//session.saveOrUpdate(user2); 會出現錯誤
session.merge(user2); // 應該使用merge()方法
transaction.commit();//再次進行提交
}
- 如果merge的物件在資料庫中不存在,merge將會進行save操作,作用等同於updateOrSave();而update因為找不到物件而報錯。
- 如果merge的物件能在資料庫中操作,merge操作和update操作效果一樣。
- 新new一個物件,如果該物件設定了ID,則這個物件就當作遊離態處理.
- merge可以持久化遊離態的物件A,持久化後的物件A仍然處於遊離態,持久化的物件A不和session關聯。
- merge返回持久化物件的副本,該副本處於持久化態。
三.get()和load()的區別
get是立即載入,load()是延遲載入。 與一個lazy 的屬性設定值有關。 如果是get()的時候,
User user=session.get(User.class,1); //會在這裡去資料庫中進行查詢
如果是load()的時候,
User user=session.load(User.class,1); //不會去資料庫中查詢
System.out.println(user.getUserName()); //會去資料庫中進行相應的查詢
另外,如果查詢出的資料不存在時:
@Test
public void test3(){
Session session=HibernateUtil.getSession();
User user=session.get(User.class,100); //不存在id為100的值
System.out.println(user.toString());
}
會丟擲空指向異常。即get()的返回值為null. 如果是load()的話,
@Test
public void test3(){
Session session=HibernateUtil.getSession();
User user=session.load(User.class,100); //不存在id為100的值
System.out.println(user.toString());
}
會丟擲ObjectNotFoundExcetpion 異常。
四. close(),flush(),clear()和evict()
close()為關閉Session,表示斷開與資料庫的連線。 clear()為清空快取,清空Session中的所有的物件,但不包括正在操作的物件。 Session中可以儲存很多的物件,如果這個物件正在被操作,當session.clear()時,會把其餘的物件給清空。 flush(),是將緩衝區的物件重新整理到資料庫中,與資料庫進行同步。 可以設定flushModel的值,以前常用setFlushMode()方法,但這個方法已經被廢除了,現在常用setHibernateFlushMode()方法。 其中,FlushMode的常用值為:
MANUAL(0), // 手動方式
COMMIT(5), //commit提交時
AUTO(10), //自動,預設的
ALWAYS(20); //任何程式碼都會
session.evict(user); //只清空當前 的user物件,不會清除其他的物件。
謝謝!!!