Hibernate面試題分析
1. Hibernate 的檢索方式有哪些 ?
① 導航對象圖檢索
② OID檢索
③ HQL檢索
④ QBC檢索
⑤ 本地SQL檢索
2. 在 Hibernate 中 Java 對象的狀態有哪些?
①. 臨時狀態(transient):不處於 Session 的緩存中。OID 為null 或等於 id 的 unsaved-value 屬性值
②. 持久化狀態(persistent):加入到 Session 的緩存中。
③. 游離狀態(detached):已經被持久化,但不再處於 Session 的緩存中。
3.Session的清理和清空有什么區別?
清理緩存調用的是 session.flush() 方法. 而清空調用的是 session.clear() 方法.
Session 清理緩存是指按照緩存中對象的狀態的變化來同步更新數據庫,但不清空緩存;清空是把Session 的緩存置空, 但不同步更新數據庫;
4.load()和get()的區別
①:如果數據庫中,沒有 OID 指定的對象。通過 get方法加載,則返回的是一個null;通過load加載,則返回一個代理對象,如果后面代碼如果調用對象的某個屬性會拋出異常:org.hibernate.ObjectNotFoundException;
②:load 支持延遲加載,get不支持延遲加載。
5.hibernate 優缺點
①. 優點:
>對 JDBC 訪問數據庫的代碼做了封裝,簡化了數據訪問層繁瑣的重復性代碼
>映射的靈活性, 它支持各種關系數據庫, 從一對一到多對多的各種復雜關系.
>非侵入性、移植性會好
>緩存機制: 提供一級緩存和二級緩存
②. 缺點:
>無法對 SQL 進行優化
>框架中使用 ORM原則, 導致配置過於復雜
>執行效率和原生的JDBC 相比偏差: 特別是在批量數據處理的時候
>不支持批量修改、刪除
6. 描述使用 Hibernate 進行大批量更新的經驗.
直接通過 JDBC API 執行相關的 SQl 語句或調用相關的存儲過程是最佳的方式
7.Hibernate 的OpenSessionView 問題
①. 用於解決懶加載異常, 主要功能就是把 Hibernate Session 和一個請求的線程綁定在一起, 直到頁面完整輸出, 這樣就可以保證頁面讀取數據的時候 Session 一直是開啟的狀態, 如果去獲取延遲加載對象也不會報錯。
②. 問題: 如果在業務處理階段大批量處理數據, 有可能導致一級緩存里的對象占用內存過多導致內存溢出, 另外一個是連接問題: Session 和數據庫 Connection 是綁定在一起的, 如果業務處理緩慢也會導致數據庫連接得不到及時的釋放, 造成連接池連接不夠. 所以在並發量較大的項目中不建議使用此種方式, 可以考慮使用迫切左外連接 (LEFT OUTER JOIN FETCH) 或手工對關聯的對象進行初始化.
③. 配置 Filter 的時候要放在 Struts2 過濾器的前面, 因為它要頁面完全顯示完后再退出.
8.Hibernate 中getCurrentSession() 和 openSession() 的區別 ?
①. getCurrentSession() 它會先查看當前線程中是否綁定了 Session, 如果有則直接返回, 如果沒有再創建. 而openSession() 則是直接 new 一個新的 Session 並返回。
②. 使用ThreadLocal 來實現線程 Session 的隔離。
③. getCurrentSession() 在事務提交的時候會自動關閉 Session, 而 openSession() 需要手動關閉.
9.如何調用原生 SQL ?
調用 Session 的doWork() 方法.
10.說說 Hibernate 的緩存:
Hibernate緩存包括兩大類:Hibernate一級緩存和Hibernate二級緩存:
1). Hibernate一級緩存又稱為“Session的緩存”,它是內置的,不能被卸載。由於Session對象的生命周期通常對應一個數據庫事務或者一個應用事務,因此它的緩存是事務范圍的緩存。在第一級緩存中,持久化類的每個實例都具有唯一的OID。
2).Hibernate二級緩存又稱為“SessionFactory的緩存”,由於SessionFactory對象的生命周期和應用程序的整個過程對應,因此Hibernate二級緩存是進程范圍或者集群范圍的緩存,有可能出現並發問題,因此需要采用適當的並發訪問策略,該策略為被緩存的數據提供了事務隔離級別。第二級緩存是可選的,是一個可配置的插件,在默認情況下,SessionFactory不會啟用這個插件。
當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,如果配置了二級緩存,那么從二級緩存中查;如果都查不到,再查詢數據庫,把結果按照ID放入到緩存刪除、更新、增加數據的時候,同時更新緩存。