hibernate笔记--缓存机制之 一级缓存(session缓存)
一級緩存:
又稱為session緩存,它和session生命周期相同,周期非常短.是事務級別的緩存:
還是以Book和Category這兩個表為例,我們用代碼觀察一個緩存的存在:
假設現在我要去查詢id=1的Book信息:
List<Book> list =(List) session.createQuery("from Book").list();System.out.println(list.get(0).getName());Book book = (Book)session.get(Book.class, 1);System.out.println(book.getName());我這里先查詢了所有的Book,打印出了index=0,即id=1的那本書的書名,接著用get方法再次獲取了id=1的Book,我們看一下控制臺的打印信息:
通過打印信息我們能發現一個現象,當第二次我們使用get(..)方法去查詢時,我們如愿得到了書名,但卻沒有select語句,說明了什么問題?說明了使用get()方法獲取id=1的Book時,hibernate并沒有去訪問數據庫,而是在某一個地方就得到了這個id=1的Book的信息,不難發現,我們第一次使用createQuery()時,其實已經得到了這條Book的信息,而hibernate將這些信息放到了一個緩存里,當執行查詢語句時,hibernate沒有著急的立即訪問數據庫去查詢,而是先到這個緩存里去找找有沒有他所要查詢的數據,如果有的話,那就皆大歡喜了,不需要訪問數據庫,提高了效率,而這個緩存.就是我們所說的一級緩存,也叫session緩存.
同時我們也能知道,get方法使用了一級緩存,用get查詢數據時,首先檢查緩存中是否有該數據,如果有,直接從緩存中獲取該數據直接返回,如果沒有,再去訪問數據庫查找.load也支持一級緩存,但是同時load同時也支持延遲加載.要注意.
接下繼續測試代碼:
List<Book> list =(List) session.createQuery("from Book").list(); System.out.println(list.get(0).getName());list =(List) session.createQuery("from Book").list();System.out.println(list.get(0).getName())在代碼中,我們執行了兩次session.createQuery(),如果只打印一條sql語句,說明list查詢也支持一級緩存,打印結果是這樣:
很不幸,控制臺打印出了兩條sql語句,這就說明了:
list查詢不支持一級緩存,但list查詢會把返回的結果保存到session緩存,同理uniqueResult()查詢也是如此.
接下來繼續測試:
List<Book> list =(List) session.createQuery("from Book").list();System.out.println(list.get(0).getName());Iterator<Book> iter = session.createQuery("from Book").iterate();while(iter.hasNext()){System.out.println(iter.next().getName());}這里我們第一次使用list查詢得到所有Book信息,然后用iterate查詢,得到一個包含所有Book的迭代器集合,那么他會不會支持一級緩存,這是控制臺打印的信息:
乍一看,第二次查詢的時候依然打出了sql語句,看來iterate查詢是不會先去session中查找的了,但是仔細觀察第一條sql語句,可以發現,它僅僅查詢了Book的id,但依然打印出了每本書的書名.說明了,iterate依然是在緩存中查詢的數據,所以,iterate是支持一級緩存的,同樣它執行的查詢,也會把返回結果保存到session緩存中.
` 現在再來看一下管理session的幾個方法.
下面用代碼演示一下evict,和clear方法:
Book book =(Book) session.get(Book.class,1);System.out.println(book.getName());session.evict(book);//b表示干掉session中保存的所有對象,當然也包括Book對象//session.clear()book =(Book) session.get(Book.class,1);System.out.println(book.getName());按照我們的設想,由于執行第二次查詢之前,我們通過session.evict(book)方法,干掉了book對象,再次查詢時會去訪問數據庫,來看一下控制臺打印結果是不是這樣的:
果然如此,跟我們料想的一樣.
?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的hibernate笔记--缓存机制之 一级缓存(session缓存)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeforces Round #34
- 下一篇: 使用Apache下poi创建和读取exc