Hibernate最全面試題

Hibernate常見面試題

Hibernate工做原理及爲何要用?

Hibernate工做原理及爲何要用?html

  1. 讀取並解析配置文件
  2. 讀取並解析映射信息,建立SessionFactory
  3. 打開Sesssion
  4. 建立事務Transation
  5. 持久化操做
  6. 提交事務
  7. 關閉Session
  8. 關閉SesstionFactory

 

 

使用Hibernate框架就不用咱們寫不少繁瑣的SQL語句。Hibernate實現了ORM,可以將對象映射成數據庫表,從而簡化咱們的開發!mysql

Hibernate是如何延遲加載(懶加載)?

Hibernate是如何延遲加載(懶加載)?面試

經過設置屬性lazy進行設置是否須要懶加載spring

當Hibernate在查詢數據的時候,數據並無存在與內存中,當程序真正對數據的操做時,對象才存在與內存中,就實現了延遲加載,他節省了服務器的內存開銷,從而提升了服務器的性能。sql

Hibernate中怎樣實現類之間的關係?(如:一對多、多對多的關係)

Hibernate中怎樣實現類之間的關係?(如:一對多、多對多的關係)數據庫

它們經過配置文件中的many-to-one、one-to-many、many-to-many來實現類之間的關聯關係的。緩存

hibernate的三種狀態之間如何轉換

hibernate的三種狀態之間如何轉換安全

Hibernate中對象的狀態:服務器

  • 臨時/瞬時狀態
  • 持久化狀態
  • 遊離狀態

臨時/瞬時狀態

當咱們直接new出來的對象就是臨時/瞬時狀態的..微信

  • 該對象尚未被持久化【沒有保存在數據庫中】
  • 不受Session的管理

 

這裏寫圖片描述

 

持久化狀態

當保存在數據庫中的對象就是持久化狀態了

  • 當調用session的save/saveOrUpdate/get/load/list等方法的時候,對象就是持久化狀態
  • 在數據庫有對應的數據
  • 受Session的管理
  • 當對對象屬性進行更改的時候,會反映到數據庫中!

 

這裏寫圖片描述

 

咱們來測試一下:當對對象屬性進行更改的時候,會反映到數據庫中!

session.save(idCard);
        idCard.setIdCardName("我是測試持久化對象");

 

這裏寫圖片描述

 

遊離狀態

當Session關閉了之後,持久化的對象就變成了遊離狀態了...

  • 不處於session的管理
  • 數據庫中有對應的記錄

 

這裏寫圖片描述

 

有了上面的基礎,咱們就很容易說出它們之間的轉換了

  • new出來的對象是瞬時狀態->保存到數據庫中(受Session管理)就是持久化狀態->將session close掉就是遊離狀態

比較hibernate的三種檢索策略優缺點

比較hibernate的三種檢索策略優缺點

當即檢索:

  • 優勢: 對應用程序徹底透明,無論對象處於持久化狀態,仍是遊離狀態,應用程序均可以方便的從一個對象導航到與它關聯的對象;
  • 缺點: 1.select語句太多;2.可能會加載應用程序不須要訪問的對象白白浪費許多內存空間;
  • 當即檢索:lazy=false

延遲檢索:

  • 優勢: 由應用程序決定須要加載哪些對象,能夠避免可執行多餘的select語句,以及避免加載應用程序不須要訪問的對象。所以能提升檢索性能,而且能節省內存空間;
  • 缺點: 應用程序若是但願訪問遊離狀態代理類實例,必須保證他在持久化狀態時已經被初始化;
  • 延遲加載:lazy=true

迫切左外鏈接檢索:

  • 優勢: 1對應用程序徹底透明,無論對象處於持久化狀態,仍是遊離狀態,應用程序均可以方便地衝一個對象導航到與它關聯的對象。2使用了外鏈接,select語句數目少;
  • 缺點: 1 可能會加載應用程序不須要訪問的對象,白白浪費許多內存空間;2複雜的數據庫錶鏈接也會影響檢索性能;
  • 預先抓取: fetch=「join」

hibernate都支持哪些緩存策略

hibernate都支持哪些緩存策略

usage的屬性有4種:

  • 放入二級緩存的對象,只讀(Read-only);
  • 非嚴格的讀寫(Nonstrict read/write)
  • 讀寫; 放入二級緩存的對象能夠讀、寫(Read/write);
  • 基於事務的策略(Transactional)

hibernate裏面的sorted collection 和ordered collection有什麼區別

hibernate裏面的sorted collection 和ordered collection有什麼區別

sorted collection

  • 是在內存中經過Java比較器進行排序的

ordered collection

  • 是在數據庫中經過order by進行排序的

對於比較大的數據集,爲了不在內存中對它們進行排序而出現 Java中的OutOfMemoryError,最好使用ordered collection。

說下Hibernate的緩存機制

說下Hibernate的緩存機制

一級緩存:

  • Hibenate中一級緩存,也叫作session的緩存,它能夠在session範圍內減小數據庫的訪問次數! 只在session範圍有效! Session關閉,一級緩存失效!
  • 只要是持久化對象狀態的,都受Session管理,也就是說,都會在Session緩存中!
  • Session的緩存由hibernate維護,用戶不能操做緩存內容; 若是想操做緩存內容,必須經過hibernate提供的evit/clear方法操做

二級緩存:

  • 二級緩存是基於應用程序的緩存,全部的Session均可以使用
  • Hibernate提供的二級緩存有默認的實現,且是一種可插配的緩存框架!若是用戶想用二級緩存,只須要在hibernate.cfg.xml中配置便可; 不想用,直接移除,不影響代碼。
  • 若是用戶以爲hibernate提供的框架框架很差用,本身能夠換其餘的緩存框架或本身實現緩存框架均可以
  • Hibernate二級緩存:存儲的是經常使用的類

 

這裏寫圖片描述

 

Hibernate的查詢方式有幾種

Hibernate的查詢方式有幾種

  • 對象導航查詢(objectcomposition)
  • HQL查詢
    • 一、 屬性查詢
    • 二、 參數查詢、命名參數查詢
    • 三、 關聯查詢
    • 四、 分頁查詢
    • 五、 統計函數
  • Criteria 查詢
  • SQLQuery本地SQL查詢

如何優化Hibernate?

如何優化Hibernate?

  • Ø 數據庫設計調整
  • Ø HQL優化
  • Ø API的正確使用(如根據不一樣的業務類型選用不一樣的集合及查詢API)
  • Ø 主配置參數(日誌,查詢緩存,fetch_size, batch_size等)
  • Ø 映射文件優化(ID生成策略,二級緩存,延遲加載,關聯優化)
  • Ø 一級緩存的管理
  • Ø 針對二級緩存,還有許多特有的策略

詳情可參考資料:

談談Hibernate中inverse的做用

談談Hibernate中inverse的做用

inverse屬性默認是false,就是說關係的兩端都來維護關係。

  • 好比Student和Teacher是多對多關係,用一箇中間表TeacherStudent維護。Gp)
  • 若是Student這邊inverse=」true」, 那麼關係由另外一端Teacher維護,就是說當插入Student時,不會操做TeacherStudent表(中間表)。只有Teacher插入或刪除時纔會觸發對中間表的操做。因此兩邊都inverse=」true」是不對的,會致使任何操做都不觸發對中間表的影響;當兩邊都inverse=」false」或默認時,會致使在中間表中插入兩次關係。

若是表之間的關聯關係是「一對多」的話,那麼inverse只能在「一」的一方來配置!

詳情可參考:

JDBC hibernate 和 ibatis 的區別

JDBC hibernate 和 ibatis 的區別

jdbc:手動

  • 手動寫sql
  • delete、insert、update要將對象的值一個一個取出傳到sql中,不能直接傳入一個對象。
  • select:返回的是一個resultset,要從ResultSet中一行一行、一個字段一個字段的取出,而後封裝到一個對象中,不直接返回一個對象。

ibatis的特色:半自動化

  • sql要手動寫
  • delete、insert、update:直接傳入一個對象
  • select:直接返回一個對象

hibernate:全自動

  • 不寫sql,自動封裝
  • delete、insert、update:直接傳入一個對象
  • select:直接返回一個對象

在數據庫中條件查詢速度很慢的時候,如何優化?

在數據庫中條件查詢速度很慢的時候,如何優化?

  1. 建索引
  2. 減小表之間的關聯
  3. 優化sql,儘可能讓sql很快定位數據,不要讓sql作全表查詢,應該走索引,把數據量大的表排在前面
  4. 簡化查詢字段,沒用的字段不要,已經對返回結果的控制,儘可能返回少許數據

詳情可參考:

什麼是SessionFactory,她是線程安全麼

什麼是SessionFactory,她是線程安全麼

SessionFactory 是Hibrenate單例數據存儲和線程安全的,以致於能夠多線程同時訪問。一個SessionFactory 在啓動的時候只能創建一次。SessionFactory應該包裝各類單例以致於它能很簡單的在一個應用代碼中儲存.

get和load區別

get和load區別

  • get()當即查詢

 

這裏寫圖片描述

 

  • load()懶加載

 

這裏寫圖片描述

 

  • 1)get若是沒有找到會返回null, load若是沒有找到會拋出異常。
  • 2)get會先查一級緩存, 再查二級緩存,而後查數據庫;load會先查一級緩存,若是沒有找到,就建立代理對象, 等須要的時候去查詢二級緩存和數據庫。

merge的含義:

merge的含義:

  • 若是session中存在相同持久化標識(identifier)的實例,用用戶給出的對象的狀態覆蓋舊有的持久實例
  • 若是session沒有相應的持久實例,則嘗試從數據庫中加載,或建立新的持久化實例,最後返回該持久實例
  • 用戶給出的這個對象沒有被關聯到session上,它依舊是脫管的

詳情可參考:

persist和save的區別

persist和save的區別

  • persist不保證當即執行,可能要等到flush;
  • persist不更新緩存;
  • save, 把一個瞬態的實例持久化標識符,及時的產生,它要返回標識符,因此它會當即執行Sql insert
  • 使用 save() 方法保存持久化對象時,該方法返回該持久化對象的標識屬性值(即對應記錄的主鍵值);
  • 使用 persist() 方法來保存持久化對象時,該方法沒有任何返回值

參考資料:

主鍵生成 策略有哪些

主鍵生成 策略有哪些

主鍵的自動生成策略

  • identity 自增加(mysql,db2)
  • sequence 自增加(序列), oracle中自增加是以序列方法實現**
  • native 自增加【會根據底層數據庫自增加的方式選擇identity或sequence】
    • 若是是mysql數據庫, 採用的自增加方式是identity
    • 若是是oracle數據庫, 使用sequence序列的方式實現自增加
  • increment 自增加(會有併發訪問的問題,通常在服務器集羣環境使用會存在問題。)

指定主鍵生成策略爲手動指定主鍵的值

  • assigned

指定主鍵生成策略爲UUID生成的值

  • uuid

foreign(外鍵的方式)

簡述hibernate中getCurrentSession和openSession區別

簡述hibernate中getCurrentSession和openSession區別

  • 一、getCurrentSession會綁定當前線程,而openSession不會,由於咱們把hibernate交給咱們的spring來管理以後,咱們是有事務配置,這個有事務的線程就會綁定當前的工廠裏面的每個session,而openSession是建立一個新session。
  • 二、getCurrentSession事務是有spring來控制的,而openSession須要咱們手動開啓和手動提交事務,
  • 三、getCurrentSession是不須要咱們手動關閉的,由於工廠會本身管理,而openSession須要咱們手動關閉。
  • 四、而getCurrentSession須要咱們手動設置綁定事務的機制,有三種設置方式,jdbc本地的Thread、JTA、第三種是spring提供的事務管理機制org.springframework.orm.hibernate4.SpringSessionContext,並且srping默認使用該種事務管理機制

Hibernate中的命名SQL查詢指的是什麼?

Hibernate中的命名SQL查詢指的是什麼?

  • 命名查詢指的是用<sql-query>標籤在影射文檔中定義的SQL查詢,能夠經過使用Session.getNamedQuery()方法對它進行調用。命名查詢使你可使用你所指定的一個名字拿到某個特定的查詢。
  • Hibernate中的命名查詢可使用註解來定義,也可使用我前面提到的xml影射問句來定義。在Hibernate中,@NameQuery用來定義單個的命名查詢,@NameQueries用來定義多個命名查詢。

爲何在Hibernate的實體類中要提供一個無參數的構造器這一點很是重要?

爲何在Hibernate的實體類中要提供一個無參數的構造器這一點很是重要?

每一個Hibernate實體類必須包含一個 無參數的構造器, 這是由於Hibernate框架要使用Reflection API,經過調用Class.newInstance()來建立這些實體類的實例。若是在實體類中找不到無參數的構造器,這個方法就會拋出一個InstantiationException異常。

可不能夠將Hibernate的實體類定義爲final類?

可不能夠將Hibernate的實體類定義爲final類?

能夠將Hibernate的實體類定義爲final類,但這種作法並很差。由於Hibernate會使用代理模式在延遲關聯的狀況下提升性能,若是你把實體類定義成final類以後,由於Java不容許對final類進行擴展,因此Hibernate就沒法再使用代理了, 如此一來就限制了使用能夠提高性能的手段。

最後

參考資料:

若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y

相關文章
相關標籤/搜索