你們好,我是Java最全面試題庫的提褲姐,今天有點事更新晚了,可是斷更是不可能斷更的,這輩子都不可能斷更的。好了,今天這篇是JavaEE系列的第六篇,主要總結了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所需的不一樣的鎖定級別:瀏覽器
臨時態(瞬時態/Transient)
不存在於session中,也不存在於數據庫中的數據,被稱爲臨時態。
好比:剛剛使用new關鍵字建立出的對象。緩存
持久態(Persistent)
存在於session中,事務還未提交,提交以後最終會進入數據庫的數據,被稱爲持久態。
好比:剛剛使用session.save()操做的對象。安全
遊離態(脫管態/Detached)
存在於數據庫中,但不存在於session中的數據,被稱爲遊離態。
好比:使用了session.save(),而且事務已經提交以後,對象進入數據庫,就變成了遊離態。session
當對象由瞬時狀態(Transient)一save()時,就變成了持久化狀態
;
當咱們在Session裏存儲對象的時候,實際是在Session的Map裏存了一份, 也就是它的緩存裏放了一份,而後,又到數據庫裏存了一份,在緩存裏這一份叫持久對象(Persistent)。 Session 一 Close()了,它的緩存也都關閉了,整個Session也就失效了,這個時候,這個對象變成了遊離狀態(Detached)
,但數據庫中仍是存在的。
當遊離狀態(Detached)update()時,又變爲了持久狀態(Persistent)。
當持久狀態(Persistent)delete()時,又變爲了瞬時狀態(Transient)
, 此時,數據庫中沒有與之對應的記錄。併發
hibernate分爲2級緩存 一級緩存
又叫session緩存,又叫事務級緩存,生命週期從事務開始到事務結束,一級緩存是hibernate自帶的,暴力使用,當咱們一建立session就已有這個緩存了。數據庫就會自動往緩存存放, 二級緩存
是hibernate提供的一組開放的接口方式實現的,都是經過整合第三方的緩存框架來實現的,二級緩存又叫sessionFactory的緩存,能夠跨session訪問。經常使用的EHcache、OScache,這個須要一些配置。框架
當咱們每次 查詢數據的時候,首先是到一級緩存查看是否存在該對象,若是有直接返回,若是沒有就去二級緩存進行查看,若是有直接返回,若是沒有在發送SQL到數據庫查詢數據,
當SQL發送查詢回該數據的時候,hibernate會把該對象以主鍵爲標記的形式存儲到二級緩存和一級緩存,若是返回的是集合,會把集合打散而後以主鍵的形式存儲到緩存。一級緩存和二級緩存只針對以ID查詢的方式生效,get、load方法。
Configuration 接口
:配置Hibernate,根據其啓動hibernate,建立SessionFactory 對象SessionFactory 接口
:初始化Hibernate,充當數據存儲源的代理,建立session 對象,sessionFactory 是線程安全的,意味着它的同一個實例能夠被應 用的多個線程共享,是重量級、二級緩存Session 接口
:負責保存、更新、刪除、加載和查詢對象,是線程不安全的, 避免多個線程共享同一個session,是輕量級、一級緩存Transaction 接口
:管理事務Query 和Criteria 接口
:執行數據庫的查詢。當即加載
,load 是延時加載
。load 會先查一級緩存,若是沒有找到,就建立代理對象,等須要的時候去查詢二級緩存和數據庫。(這裏就體現 load 的延遲加載的特性。)
null
,load 若是沒有找到會拋出異常
。session.load()
方法來加載一個對象時,此時並不會發出 sql 語句,當前獲得的這個對象實際上是一個代理對象,這個代理對象只保存了實體對象的 id 值,只有當咱們要使用這個對象,獲得其它屬性時,這個時候纔會發出 sql 語句,從數據庫中去查詢咱們的對象;相對於 load 的延遲加載方式,get 就直接的多,當咱們使用session.get()
方法來獲得一個對象時,無論咱們使不使用這個對象,此時都會發出 sql 語句去從數據庫中查詢出來。
4種:
HQL
經過Hibernate提供的查詢語言進行查詢。Hibernate Query lanagueEJBQL
(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 查詢更爲靈活,並且支持運行時動態天生查詢語句。
save:
執行保存操做的,對一個新new出來的對象進行保存,數據庫中沒有這個對象,若是數據庫中有,會報錯說有重複的記錄
update:
若是是對一個已經存在的託管對象進行更新,要使用update方法了,數據中有這個對象
saveOrUpdate:
這個方法是更新或者插入,有主鍵就執行更新,若是沒有主鍵就執行插入。是根據實體類對象的狀態作的不一樣操做
延遲加載機制:
延遲加載機制是爲了不一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正須要數據的時候,才真正執行數據加載操做。在 Hibernate 中提供了對實體對象的延遲加載以及對集合的延遲加載,另外在 Hibernate3 中還提供了對屬性的延遲加載。
延遲加載的過程:
經過代理(Proxy)機制來實現延遲加載。Hibernate 從數據庫獲取某一個對象數據時、獲取某一個對象的集合屬性值時,或獲取某一個對象所關聯的另外一個對象時,因爲沒有使用該對象的數據(除標識符外),Hibernate 並不從數據庫加載真正的數據,而只是爲該對象建立一個代理對象來表明這個對象,這個對象上的全部屬性都爲默認值;只有在真正須要使用該對象的數據時才建立這個真正的對象,真正從數據庫中加載它的數據。
相同點:
SessionFactory 生成 Session,最後由 Session 來開啓執行事務和 SQL 語句。其中 SessionFactoryBuider,
SessionFactory,Session 的生命週期都是差很少的。
Mybatis 優點:
Hibernate 優點: