1:持久化對象的四種狀態
四種狀態分別為臨時狀態、持久化狀態、游離狀態和刪除狀態。
這幾種狀態可以相互轉換
狀態轉換圖:
代碼演示:
// 開啟事務 Transaction transaction = session.beginTransaction(); Book book = new Book(); // 瞬時態(沒有OID,未與Session關聯) book.setName("hibernate精通"); book.setPrice(56d); session.save(book);// 持久態(具有OID,與Session關聯) // 提交事務,關閉Session transaction.commit(); session.close(); System.out.println(book.getId()); // 脫管態(具有 OID,與Session斷開關聯)
持久化對象之間轉變1.瞬態對象——通過new關鍵字獲取
瞬時——持久:save、saveOrUpdate(都是通過session獲得)
瞬時——脫管:對象.setID(1);為瞬時對象設置新的OID
2.持久化對象——通過get/load、Query查詢獲得
持久——瞬時:delete(被刪除持久化對象,不建議再次使用)
持久——脫管:evict(清楚一級緩存中某個對象)、close(關閉Session,清除一級緩存)、clear(清楚一級緩存所有對象)
3.脫管對象:無法直接獲得
脫管——瞬時:對象.setID(null);刪除對象OID
脫管——持久:update、saveOrUpdate、lock
4.刪除狀態 :無法直接獲得
持久——刪除:對象.delete();
游離——刪除: 對象.delete();
2:一級緩存
也成為session緩存,它和session生命周期相同,周期比較短,屬於事務隔離級別。
hibernate的緩存是通過集合實現的,hibernate中封裝了list和map的集合。hibernate向一級緩存中存放數據時,同時保存快照數據,當執行flush()時,會對比一級緩存中的數據和快照中的數據是否一致,如果不一致,則執行更新。
用處:
當要查詢的數據在緩存中已經存在時,hibernate將不會再向數據庫發送查詢語句,而是直接從緩存中獲取對象。
session.get()、load(支持一級緩存。createQuery()不支持一級緩存,即即使是兩次相同的查詢,獲得list也是相同的,也會向數據庫發起2次查詢
操作:
1:flush()
將緩存同步到數據庫,首先會將緩存數據和快照區數據進行對比,如果相同,就不會發送update()語句,如果不同,則執行update()語句,所以不一定會很發生update()語句到數據庫。
session.beginTransaction(); // 通過ID從數據庫中獲取值,此時會產生快照 Book book1 = (Book) session.get(Book.class, 1); // 修改屬性值 book1.setName("xxx"); // 手動flush,刷新緩存到數據庫,此時只是生成SQL語句,但是數據庫中並沒有發生變化,只有commit后,數據庫才會發生相應的變化。 session.flush(); // 手動提交事務 session.getTransaction().commit(); // 關閉session的資源 session.close();
2:refresh()
將數據庫中的數據同步到緩存中,這個過程一定會產生更新語句,同步一級緩存和快照
session.beginTransaction(); // 從數據庫中查詢book,並放置到Session緩存中一份 Book book1 = (Book) session.get(Book.class, 1); //修改緩存對象的值 book1.setName("xxx"); //又進行了一次查詢操作,此時把快照中的數據與數據庫一致 session.refresh(book1); System.out.println(book1); // 4.提交食物 session.getTransaction().commit(); // 5.關閉session資源 session.close();
3:clear()
清除所有對象的一級緩存,對對象的所有操作,全部失效,回復到當初和快照一樣
// 啟動事務操作 session.beginTransaction(); // session.setFlushMode(FlushMode.MANUAL); // 通過ID從數據庫中獲取值,此時會產生快照 Book book1 = (Book) session.get(Book.class, 1); // 修改屬性值 book1.setName("xxx"); //清除一級緩存操作,此時當作事務提交的時候,數據庫中並沒有發生任何的變化 session.clear(); // 手動提交事務 session.getTransaction().commit(); // 關閉session的資源 session.close();
4:evict()
對指定的對象清除一級緩存
session.beginTransaction(); //當執行一次操作后,會把對象放置到Session緩存中 Book book1 = (Book) session.get(Book.class, 1); Book book2 = (Book) session.get(Book.class, 2); session.evict(book2); // 從緩存中清除book2對象所做的修改 // 當再次執行操作時,book2還會發出SQL語句操作 Book book11 = (Book) session.get(Book.class, 1); Book book22 = (Book) session.get(Book.class, 2); // 手動提交事務 session.getTransaction().commit(); // 關閉資源 session.close();