2007年8月5日 星期日

saveOrUpdate 的使用時機

當我們呼叫 session.saveOrUpdate() 時,何時會使用 save(), 何時會使用 update()
取決於物件的id屬性值, 與 hbm.xml 中的 unsaved-value 設定.

Hibernate 會利用該設定的內容, 來比對物件的主鍵屬性.
若主鍵的屬性與 unsaved-value 的設定內容相符(Hibernate 把認為該物件為 Transient Object), 則 Hibernate 送出 session.save(),進行儲存,反之(Hibernate 把認為該物件為 Persistence Object)則呼叫 session.update().

例如:

...
session.beginTransaction();

Person aPerson = new Person();
aPerson.setFirstname("Foo");

Person aPersonUpd = new Person();
aPersonUpd.setId(new Long(2));
aPersonUpd.setFirstname("Foo");

session.saveOrUpdate(aPerson);
session.saveOrUpdate(aPersonUpd);

...
session.getTransaction().commit();
session.close();
若您的 unsaved-value 設為 "null",
而 aPerson 物件的id屬性也為 null, 此時 Hibernate 會執行 session.save(), 資料庫變新增一筆 Person 的紀錄.

另外 aPersonUpd 已設定id為 "2", Hibernate 經由比對後, 若發現資料庫有該筆紀錄, 則會呼叫 session.update() 予以更新.

以下是幾種unsaved-value設定的說明:

1. unsaved-value="null"
為預設的設定, 當取出的物件主鍵值為 null(表示資料庫無對應的紀錄),
則呼叫 save().

2. unsaved-value="undefined"
不論該物件的id屬性塞入任何型態的資料, 都會進行檢查, 若在資料庫中找不到對應的鍵值,
則進行 session.save(), 反之呼叫 session.update().

3. unsaved-value="any"
不論該物件的ID屬性有沒有值, 一定會呼叫 session.save(), 以儲存資料.

4. unsaved-value="none"
不論該物件的ID屬性有沒有值, 一定會呼叫 session.update(), 以更新資料.

若您的主鍵設定為 "assigned" (generator class="assigned"), Hibernate 在判斷時,
會先執行 select 的SQL, 再進行鍵值的比對, 在這種狀況下, 執行 session.saveOrUpdate()
的效能會比 Hibernate的 id generator 略差, 這是值得注意的.

0 意見: