1. 程式人生 > >Hibernate的常用方法區別(六)

Hibernate的常用方法區別(六)

感謝Jie’ blog http://ilog.vip/ ,謝謝他讓我有了繼續寫下去的信念。願一起堅持,在路上… 上一章簡單介紹了Hibernate三種實體狀態(五),如果沒有看過,請觀看上一章 Hibernate的Session中提供了很多的方法,這些方法在某些方面是效果一樣的,但還是有一些不同的。下面,進行一些簡單的區分.

一. save()與saveOrUpdate()方法

save()方法的執行過程為:

  1. 系統根據指定的ID生成策略,為臨時物件生成一個唯一的OID;
  2. 將臨時物件載入到快取中,使之變成持久化物件;
  3. 提交事務時,清理快取,利用持久化物件包含的資訊生成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. 在這裡插入圖片描述

saveOrUpdate()方法,如果設定的這個物件,如果沒有Id,

@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();//再次進行提交 
	}
  1. 如果merge的物件在資料庫中不存在,merge將會進行save操作,作用等同於updateOrSave();而update因為找不到物件而報錯。
  2. 如果merge的物件能在資料庫中操作,merge操作和update操作效果一樣。
  3. 新new一個物件,如果該物件設定了ID,則這個物件就當作遊離態處理.
  4. merge可以持久化遊離態的物件A,持久化後的物件A仍然處於遊離態,持久化的物件A不和session關聯。
  5. 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物件,不會清除其他的物件。 

謝謝!!!