第二節 hibernate session介紹以及session常用方法介紹,hibernatesession
Session是java應用程式和hibernate架構之間的一個主要介面。它是從持久化服務中剝離出來的一個非常重要的API介面。
Session的主要功能是為映射的實體類的執行個體提供增刪改查操作(User.class 為被映射的實體類,new User()即為執行個體)。這些執行個體可能是以下三種狀態之一:
1) transient: 從沒有被持久化,不在Session緩衝中
2) persistent: 在Session的緩衝中。
3) detached: 曾經是persistent狀態,現在不在Session緩衝中。
transient 執行個體通過調用save(), persist() or saveOrUpdate()可以變成persistent執行個體。persistent執行個體通過調用delete可以變成transient執行個體。任何通過get()或者load()方法擷取的執行個體都是persistent執行個體。detached執行個體通過調用update(), saveOrUpdate(), lock() or replicate()可以變成persistent執行個體。transient或者detached執行個體通過調用merge()方法可以產生一個新的persistent執行個體,但是並不是他們自己,這個persistent執行個體是merge方法自己建立的。
save() 和 persist() 產生SQL insert。delete() 產生SQL delete。update() 和 merge()產生SQL update。對persistent執行個體的修改在flush時會產生SQL update。saveOrUpdate() 和 replicate()產生insert或者update。
Session介面的實作類別並沒有專門設計為安全執行緒的。相反,每個線程或者事務都應該通過SessionFactory擷取自己的執行個體。
一個典型的事務應該使用如下的形式:
Session sess = factory.openSession(); Transaction tx; try { tx = sess.beginTransaction(); //do some work ... tx.commit(); } catch (Exception e) { if (tx!=null) tx.rollback(); throw e; } finally { sess.close(); }
如果Session拋出異常,事務必須復原。同時Session被棄用,因為Session內部狀態和資料庫可能會不一致。
1 儲存對象到資料庫 session.save();
持久化transient執行個體。參數為transient執行個體,傳回值為產生的主鍵id。
按照第一節的配置,主鍵的建置原則為native(資料庫自動產生主鍵),由於資料庫使用的是mysql 5,所以是自增的主鍵產生方式。儲存對象時並不需要設定id屬性。
@Test public void testSave() { try { User user = new User(); user.setBirthday(new java.sql.Date(0)); user.setName("binyulan"); session.save(user); } catch (HibernateException e) { if (transaction != null) { transaction.rollback(); } throw e; } }
2 儲存對象到資料庫 session.persist();
持久化transient執行個體。參數為transient執行個體。這個方法和session.save()方法一樣,都是儲存對象到資料庫。但是不能設定id屬性,否則拋出異常。
@Test public void testPersist() { try { User user = new User(); user.setBirthday(new java.sql.Date(0)); user.setName("binyulan"); user.setId(13); session.persist(user); } catch (HibernateException e) { e.printStackTrace(); if (transaction != null) { transaction.rollback(); } throw e; } }
執行testPersist後拋出異常,如下:
org.hibernate.PersistentObjectException: detached entity passed to persist: com.binyulan.domain.Userat org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
user建立出來為transient執行個體,但是異常顯示是detached執行個體。所以我認為只要給對象設定了id屬性,即使沒有持久化過,也可以看做detached執行個體。
3 合并對象到資料庫 session.merge();
1) 儲存未設定id屬性的User對象,執行insert把User對象儲存到資料庫中,同時返回儲存後的User對象。
@Test public void testMerge() { try { User user = new User(); user.setBirthday(new java.sql.Date(0)); user.setName("binyulan2"); User user1 = (User) session.merge(user); //把user屬性拷貝到建立的user1對象,執行insert插入資料庫,並且返回建立的user1對象,user1包含id,在session緩衝中 System.out.println(user1 == user); //返回false。user為建立的對象,並沒有放入session緩衝。user1為建立的持久化對象,並且在session的緩衝中。 } catch (HibernateException e) { e.printStackTrace(); if (transaction != null) { transaction.rollback(); } throw e; } }
2) 儲存設定id屬性的User對象,首先執行select查詢資料庫。若資料庫中存在此id的記錄,並且與資料庫中記錄不一致,則執行update操作,
若不存在此記錄,否則執行insert操作。
@Test public void testMerge1() { try { User user = new User(); user.setBirthday(new java.sql.Date(0)); user.setName("binyulan123"); user.setId(20); /** * 把user屬性拷貝到建立的User對象,並且執行select查詢資料庫。 * 假設資料庫中存在id為20的記錄,且user對象與資料庫中記錄不一致,執行update */ User user1 = (User) session.merge(user); System.out.println(user1 == user); //返回false。user為建立的對象,不在session緩衝中,user1為建立的持久化對象,並且在session的緩衝中。 /** * 把user屬性拷貝到建立的User對象,並且執行select查詢資料庫。 * 假設資料庫中不存在id為123456789的記錄,執行insert */ user.setId(123456789L); User user2 = (User) session.merge(user); System.out.println(user2 == user); //返回false。user為建立的對象,不再session緩衝中,user2為建立的持久化對象,並且在session的緩衝中。 } catch (HibernateException e) { e.printStackTrace(); if (transaction != null) { transaction.rollback(); } throw e; } }
寫累了,明天再寫,未完待續
請勿轉載,謝謝合作