持續輸出面試題之Hibernate篇

開篇介紹

你們好,我是Java最全面試題庫的提褲姐,今天有點事更新晚了,可是斷更是不可能斷更的,這輩子都不可能斷更的。好了,今天這篇是JavaEE系列的第六篇,主要總結了Hibernate相關的問題,在後續,會沿着第一篇開篇的知識線路一直總結下去,作到日更!若是我能作到百日百更,但願你也能夠跟着百日百刷,一百天養成一個好習慣。面試

Hibernate執行流程?

  • 讀取並解析配置文件
  • 讀取並解析映射信息,建立SessionFactory
  • 打開Sesssion
  • 建立事務Transation
  • 持久化操做
  • 提交事務
  • 關閉Session
  • 關閉SesstionFactory

什麼是Hibernate的併發機制?怎麼去處理併發問題?

Hibernate併發機制:
一、Hibernate的Session對象是非線程安全的,對於單個請求,單個會話,單個的工做單元(即單個事務,單個線程),它一般只使用一次, 而後就丟棄。
若是一個Session 實例容許共享的話,那些支持併發運行的,例如Http request,session beans將會致使出現資源爭用。
若是在Http Session中有hibernate的Session的話,就可能會出現同步訪問Http Session。只要用戶足夠快的點擊瀏覽器的「刷新」, 就會致使兩個併發運行的線程使用同一個Session。sql

二、多個事務併發訪問同一塊資源,可能會引起第一類丟失更新,髒讀,幻讀,不可重複讀,第二類丟失更新一系列的問題。數據庫

解決方案:
①設置事務隔離級別
Serializable:串行化。隔離級別最高
Repeatable Read:可重複讀
Read Committed:已提交數據讀
Read Uncommitted:未提交數據讀。隔離級別最差編程

②設置鎖:樂觀鎖和悲觀鎖
樂觀鎖:使用版本號或時間戳來檢測更新丟失,在的映射中設置 optimistic-lock=」all」能夠在沒有版本或者時間戳屬性映射的狀況下實現 版本檢查,此時Hibernate將比較一行記錄的每一個字段的狀態 行級悲觀鎖:Hibernate老是使用數據庫的鎖定機制,從不在內存中鎖定對象!只要爲JDBC鏈接指定一下隔 離級別,而後讓數據庫去搞定一切就夠了。類LockMode 定義了Hibernate所需的不一樣的鎖定級別:瀏覽器

  • LockMode.UPGRADE
  • LockMode.UPGRADE_NOWAIT
  • LockMode.READ

Hibernate中的三種數據狀態?

臨時態(瞬時態/Transient)
不存在於session中,也不存在於數據庫中的數據,被稱爲臨時態。
好比:剛剛使用new關鍵字建立出的對象。緩存

持久態(Persistent)
存在於session中,事務還未提交,提交以後最終會進入數據庫的數據,被稱爲持久態。
好比:剛剛使用session.save()操做的對象。安全

遊離態(脫管態/Detached)
存在於數據庫中,但不存在於session中的數據,被稱爲遊離態。
好比:使用了session.save(),而且事務已經提交以後,對象進入數據庫,就變成了遊離態。session

Hibernate 的三種狀態之間如何轉換?

當對象由瞬時狀態(Transient)一save()時,就變成了持久化狀態
當咱們在Session裏存儲對象的時候,實際是在Session的Map裏存了一份, 也就是它的緩存裏放了一份,而後,又到數據庫裏存了一份,在緩存裏這一份叫持久對象(Persistent)。 Session 一 Close()了,它的緩存也都關閉了,整個Session也就失效了,這個時候,這個對象變成了遊離狀態(Detached),但數據庫中仍是存在的。
當遊離狀態(Detached)update()時,又變爲了持久狀態(Persistent)。
當持久狀態(Persistent)delete()時,又變爲了瞬時狀態(Transient), 此時,數據庫中沒有與之對應的記錄。併發

介紹一下Hibernate 的緩存機制?

hibernate分爲2級緩存
一級緩存又叫session緩存,又叫事務級緩存,生命週期從事務開始到事務結束,一級緩存是hibernate自帶的,暴力使用,當咱們一建立session就已有這個緩存了。數據庫就會自動往緩存存放,
二級緩存是hibernate提供的一組開放的接口方式實現的,都是經過整合第三方的緩存框架來實現的,二級緩存又叫sessionFactory的緩存,能夠跨session訪問。經常使用的EHcache、OScache,這個須要一些配置。框架

當咱們每次 查詢數據的時候,首先是到一級緩存查看是否存在該對象,若是有直接返回,若是沒有就去二級緩存進行查看,若是有直接返回,若是沒有在發送SQL到數據庫查詢數據,
當SQL發送查詢回該數據的時候,hibernate會把該對象以主鍵爲標記的形式存儲到二級緩存和一級緩存,若是返回的是集合,會把集合打散而後以主鍵的形式存儲到緩存。一級緩存和二級緩存只針對以ID查詢的方式生效,get、load方法。

說一下Hibernate的幾個核心接口?

  • Configuration 接口:配置Hibernate,根據其啓動hibernate,建立SessionFactory 對象
  • SessionFactory 接口:初始化Hibernate,充當數據存儲源的代理,建立session 對象,sessionFactory 是線程安全的,意味着它的同一個實例能夠被應 用的多個線程共享,是重量級、二級緩存
  • Session 接口:負責保存、更新、刪除、加載和查詢對象,是線程不安全的, 避免多個線程共享同一個session,是輕量級、一級緩存
  • Transaction 接口:管理事務
  • Query 和Criteria 接口:執行數據庫的查詢。

get 和 load 的區別?

  • get 是當即加載,load 是延時加載
  • get 會先查一級緩存,再查二級緩存,而後查數據庫;

load 會先查一級緩存,若是沒有找到,就建立代理對象,等須要的時候去查詢二級緩存和數據庫。(這裏就體現 load 的延遲加載的特性。)

  • get 若是沒有找到會返回 null,load 若是沒有找到會拋出異常
  • 當咱們使用 session.load()方法來加載一個對象時,此時並不會發出 sql 語句,當前獲得的這個對象實際上是一個代理對象,這個代理對象只保存了實體對象的 id 值,只有當咱們要使用這個對象,獲得其它屬性時,這個時候纔會發出 sql 語句,從數據庫中去查詢咱們的對象;

相對於 load 的延遲加載方式,get 就直接的多,當咱們使用session.get()方法來獲得一個對象時,無論咱們使不使用這個對象,此時都會發出 sql 語句去從數據庫中查詢出來。

Hibernate 有幾種查詢方式?

4種:

  • HQL 經過Hibernate提供的查詢語言進行查詢。Hibernate Query lanague
  • EJBQL(JPQL 1.0) 是EJB提供的查詢語言
  • QBC(query by cretira)經過Cretira接口進行查詢
  • QBE(query by Example) 經過Example編程接口進行查詢

從功能強弱上排序:
NativeSQL > HQL > EJBQL(JPQL 1.0) >QBC(query by cretira) >QBE(query by Example)

QBC(Query By Criteria)查詢方式是 Hibernate 提供的「 更加面向對象」的一種檢索方式。 QBC 在條件查詢上比 HQL 查詢更爲靈活,並且支持運行時動態天生查詢語句。

Hibernate中save、update和saveOrUpdate方法的不一樣之處?

save:
執行保存操做的,對一個新new出來的對象進行保存,數據庫中沒有這個對象,若是數據庫中有,會報錯說有重複的記錄
update:
若是是對一個已經存在的託管對象進行更新,要使用update方法了,數據中有這個對象
saveOrUpdate:
這個方法是更新或者插入,有主鍵就執行更新,若是沒有主鍵就執行插入。是根據實體類對象的狀態作的不一樣操做

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

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

什麼是 Hibernate 延遲加載?

延遲加載機制:
延遲加載機制是爲了不一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正須要數據的時候,才真正執行數據加載操做。在 Hibernate 中提供了對實體對象的延遲加載以及對集合的延遲加載,另外在 Hibernate3 中還提供了對屬性的延遲加載。

延遲加載的過程:
經過代理(Proxy)機制來實現延遲加載。Hibernate 從數據庫獲取某一個對象數據時、獲取某一個對象的集合屬性值時,或獲取某一個對象所關聯的另外一個對象時,因爲沒有使用該對象的數據(除標識符外),Hibernate 並不從數據庫加載真正的數據,而只是爲該對象建立一個代理對象來表明這個對象,這個對象上的全部屬性都爲默認值;只有在真正須要使用該對象的數據時才建立這個真正的對象,真正從數據庫中加載它的數據。

Hibernate 和 Mybatis 的區別?

相同點:

  • Hibernate 與 MyBatis 均可以是經過 SessionFactoryBuider 由 XML 配置文件生成 SessionFactory,而後由

SessionFactory 生成 Session,最後由 Session 來開啓執行事務和 SQL 語句。其中 SessionFactoryBuider,
SessionFactory,Session 的生命週期都是差很少的。

  • Hibernate 和 MyBatis 都支持 JDBC 和 JTA 事務處理。

Mybatis 優點:

  • MyBatis 能夠進行更爲細緻的 SQL 優化,能夠減小查詢字段。
  • MyBatis 容易掌握,而 Hibernate 門檻較高。

Hibernate 優點:

  • Hibernate 的 DAO 層開發比 MyBatis 簡單,Mybatis 須要維護 SQL 和結果映射。
  • Hibernate 對對象的維護和緩存要比 MyBatis 好,對增刪改查的對象的維護要方便。
  • Hibernate 數據庫移植性很好,MyBatis 的數據庫移植性很差,不一樣的數據庫須要寫不一樣 SQL。
  • Hibernate 有更好的二級緩存機制,可使用第三方緩存。MyBatis 自己提供的緩存機制不佳。
相關文章
相關標籤/搜索