Hibernate面试题
2019獨角獸企業重金招聘Python工程師標準>>>
什么是Hibernate的并發機制?怎么去處理并發問題?
Hibernate并發機制:
a、Hibernate的Session對象是非線程安全的,對于單個請求,單個會話,單個的工作單元(即單個事務,單個線程),它通常只使用一次,
然后就丟棄。
如果一個Session 實例允許共享的話,那些支持并發運行的,例如Http request,session beans將會導致出現資源爭用。
如果在Http Session中有hibernate的Session的話,就可能會出現同步訪問Http Session。只要用戶足夠快的點擊瀏覽器的“刷新”,
就會導致兩個并發運行的線程使用同一個Session。
b、多個事務并發訪問同一塊資源,可能會引發第一類丟失更新,臟讀,幻讀,不可重復讀,第二類丟失更新一系列的問題。
解決方案:設置事務隔離級別。
Serializable:串行化。隔離級別最高
Repeatable Read:可重復讀
Read Committed:已提交數據讀
Read Uncommitted:未提交數據讀。隔離級別最差
設置鎖:樂觀鎖和悲觀鎖。
樂觀鎖:使用版本號或時間戳來檢測更新丟失,在的映射中設置 optimistic-lock=”all”可以在沒有版本或者時間戳屬性映射的情況下實現 版本檢查,此時Hibernate將比較一行記錄的每個字段的狀態 行級悲觀鎖:Hibernate總是使用數據庫的鎖定機制,從不在內存中鎖定對象!只要為JDBC連接指定一下隔 離級別,然后讓數據庫去搞定一切就夠了。類LockMode 定義了Hibernate所需的不同的鎖定級別:LockMode.UPGRADE,LockMode.UPGRADE_NOWAIT,LockMode.READ;
2. Hibernate和spring中常出現的幾個異常
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ‘sessionFactory’ defined in ServletContext resource [/WEB-INF/applicationContext.xml]:
Initialization of bean failed; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.xindeco.myregister.pojo.MyRegisterInfo column:
password (should be mapped with insert=”false” update=”false”)
出錯原因:password 和repassword同時對應數據庫表中的password一列,同時update和insert都設為true。xml文件如下:
type="java.lang.String"
update="true"
insert="true"
access="property"
column="password"
length = "32"
/>?<property name="repassword"
type="java.lang.String"
update="false"
insert="false"
access="property"
column="password"
length = "32"
/>
解決方法:將repassword的insert和update設為false。
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ‘sessionFactory’ defined in ServletContext resource [/WEB-INF/applicationContext.xml]:
Initialization of bean failed;nested exception is org.hibernate.PropertyNotFoundException: Could not find a getter for ID in class
錯誤原因:hibernate的映射文件中ID是大寫的,而pojo的類中id是小寫的
解決方法:要么將pojo類中的id改稱大寫,要么把hibernate的映射文件中的ID改稱小寫。
3. Hibernate與jdbc的聯系
hibernate是jdbc的輕量級封裝,包括jdbc的與數據庫的連接(用hibernate.property的配置文件實現當然本質是封裝了jdbc的forname),
和查詢,刪除等代碼,都用面向對象的思想用代碼聯系起來,hibernate通過hbm 配置文件把po類的字段和數據庫的字段關聯起來比如數據庫的id,
在po類中就是pravite Long id; public Long getId() ;public setId(Long id);
然后hql語句也是面向對象的,它的查詢語句不是查詢數據庫而是查詢類的,這些實現的魔法就是xml文件,其實hibernate=封裝的jdbc+xml文件
4. Hibernate與spring的聯系
hibernate中的一些對象可以給Spring來管理,讓Spring容器來創建hibernate中一些對象實例化。例如:SessionFactory,HibernateTemplate等。
Hibernate本來是對數據庫的一些操作,放在DAO層,而Spring給業務層的方法定義了事務,業務層調用DAO層的方法,很好的將Hibernate的操作也加入到事務中來了。
5. Hibernate自帶的分頁機制是什么?如果不使用Hibernate自帶的分頁,則采用什么方式分頁?
1、hibernate自帶的分頁機制:獲得Session對象后,從Session中獲得Query對象。用Query.setFirstResult():設置要顯示的第一行數據,
Query.setMaxResults():設置要顯示的最后一行數據。
2、不使用hibernate自帶的分頁,可采用sql語句分頁,
如:5:為每頁顯示的記錄,2為當前頁: select * top 5 from table where tabId not in (select tabId top (2-1)*5 from table);
6. hibernate的對象的三種持久化狀態,并給出解釋?
不清楚hibernate的對象的三種持久化狀態,只知道hibernate對象的三種狀態,下面有介紹。
7. hibernate中一對多配置文件返回的是什么?
hibernate中一對多配置文件會相應的映射為兩張表,并且它們之間的關系是一對多的。
例如:一個student和classes表的關系 。一個學生只能是一個班的,一個班可以有多個學生。
8. update()和saveOrUpdate()的區別?
update()和saveOrUpdate()是用來對跨Session的PO進行狀態管理的。
update()方法操作的對象必須是持久化了的對象。也就是說,如果此對象在數據庫中不存在的話,就不能使用update()方法。
saveOrUpdate()方法操作的對象既可以使持久化了的,也可以使沒有持久化的對象。如果是持久化了的對象調用saveOrUpdate()則會
更新數據庫中的對象;如果是未持久化的對象使用此方法,則save到數據庫中。
9. hibernate的三種狀態之間如何轉換
當對象由瞬時狀態(Transient)一save()時,就變成了持久化狀態。
當我們在Session里存儲對象的時候,實際是在Session的Map里存了一份,
也就是它的緩存里放了一份,然后,又到數據庫里存了一份,在緩存里這一份叫持久對象(Persistent)。
Session 一 Close()了,它的緩存也都關閉了,整個Session也就失效了,
這個時候,這個對象變成了游離狀態(Detached),但數據庫中還是存在的。
當游離狀態(Detached)update()時,又變為了持久狀態(Persistent)。
當持久狀態(Persistent)delete()時,又變為了瞬時狀態(Transient),
此時,數據庫中沒有與之對應的記錄。
10. hibernate拒絕連接、服務器崩潰的原因?最少寫5個
1. db沒有打開
2. 網絡連接可能出了問題
3. 連接配置錯了
4. 驅動的driver,url是否都寫對了
5. LIB下加入相應驅動,數據連接代碼是否有誤
6. 數據庫配置可能有問題
7. 當前聯接太多了,服務器都有訪問人數限制的
8. 服務器的相應端口沒有開,即它不提供相應的服務
9 hibernate有哪些緩存,分別怎么使用?
10 你對hibernate的了解到了一個什么樣的程度?
11 寫出一個sql語句體現hibernate中一對多的關系
11. Hibernate介紹
Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。
Hibernate的核心接口一共有5個,分別為:Session、SessionFactory、Transaction、Query和Configuration。這5個核心接口在任何開發中都會用到。通過這些接口,不僅可以對持久化對象進行存取,還能夠進行事務控制。下面對這五個核心接口分別加以介紹。
?Session接口:Session接口負責執行被持久化對象的CRUD操作(CRUD的任務是完成與數據庫的交流,包含了很多常見的SQL語句。)。但需要注意的是Session對象是非線程安全的。同時,Hibernate的session不同于JSP應用中的HttpSession。這里當使用session這個術語時,其實指的是Hibernate中的session,而以后會將HttpSesion對象稱為用戶session。
?SessionFactory接口:SessionFactroy接口負責初始化Hibernate。它充當數據存儲源的代理,并負責創建Session對象。這里用到了工廠模式。需要注意的是SessionFactory并不是輕量級的,因為一般情況下,一個項目通常只需要一個SessionFactory就夠,當需要操作多個數據庫時,可以為每個數據庫指定一個SessionFactory。
?Configuration接口:Configuration接口負責配置并啟動Hibernate,創建SessionFactory對象。在Hibernate的啟動的過程中,Configuration類的實例首先定位映射文檔位置、讀取配置,然后創建SessionFactory對象。
?Transaction接口:Transaction接口負責事務相關的操作。它是可選的,開發人員也可以設計編寫自己的底層事務處理代碼。
?Query和Criteria接口:Query和Criteria接口負責執行各種數據庫查詢。它可以使用HQL語言或SQL語句兩種表達方式。
12. Hibernate主鍵介紹
Assigned
Assigned方式由程序生成主鍵值,并且要在save()之前指定否則會拋出異常
特點:主鍵的生成值完全由用戶決定,與底層數據庫無關。用戶需要維護主鍵值,在調用session.save()之前要指定主鍵值。
Hilo
Hilo使用高低位算法生成主鍵,高低位算法使用一個高位值和一個低位值,然后把算法得到的兩個值拼接起來作為數據庫中的唯一主鍵。Hilo方式需要額外的數據庫表和字段提供高位值來源。默認請況下使用的表是
hibernate_unique_key,默認字段叫作next_hi。next_hi必須有一條記錄否則會出現錯誤。
特點:需要額外的數據庫表的支持,能保證同一個數據庫中主鍵的唯一性,但不能保證多個數據庫之間主鍵的唯一性。Hilo主鍵生成方式由Hibernate 維護,所以Hilo方式與底層數據庫無關,但不應該手動修改hi/lo算法使用的表的值,否則會引起主鍵重復的異常。
Increment
Increment方式對主鍵值采取自動增長的方式生成新的主鍵值,但要求底層數據庫的支持Sequence。如Oracle,DB2等。需要在映射文件xxx.hbm.xml中加入Increment標志符的設置。
特點:由Hibernate本身維護,適用于所有的數據庫,不適合多進程并發更新數據庫,適合單一進程訪問數據庫。不能用于群集環境。
Identity
Identity當時根據底層數據庫,來支持自動增長,不同的數據庫用不同的主鍵增長方式。
特點:與底層數據庫有關,要求數據庫支持Identity,如MySQl中是auto_increment, SQL Server 中是Identity,支持的數據庫有MySql、SQL Server、DB2、Sybase和HypersonicSQL。 Identity無需Hibernate和用戶的干涉,使用較為方便,但不便于在不同的數據庫之間移植程序。
Sequence
Sequence需要底層數據庫支持Sequence方式,例如Oracle數據庫等
特點:需要底層數據庫的支持序列,支持序列的數據庫有DB2、PostgreSql、Qracle、SAPDb等在不同數據庫之間移植程序,特別從支持序列的數據庫移植到不支持序列的數據庫需要修改配置文件
Native
Native主鍵生成方式會根據不同的底層數據庫自動選擇Identity、Sequence、Hilo主鍵生成方式
特點:根據不同的底層數據庫采用不同的主鍵生成方式。由于Hibernate會根據底層數據庫采用不同的映射方式,因此便于程序移植,項目中如果用到多個數據庫時,可以使用這種方式。
UUID
UUID使用128位UUID算法生成主鍵,能夠保證網絡環境下的主鍵唯一性,也就能夠保證在不同數據庫及不同服務器下主鍵的唯一性。
特點;能夠保證數據庫中的主鍵唯一性,生成的主鍵占用比較多的存貯空間
Foreign GUID
Foreign用于一對一關系中。GUID主鍵生成方式使用了一種特殊算法,保證生成主鍵的唯一性,支持SQL Server和MySQL
13. Hibernate源碼中幾個包的作用簡要介紹
net.sf.hibernate.* 該包的類基本上都是接口類和異常類
net.sf.hibernate.cache.* JCS的實現類
net.sf.hibernate.cfg.* 配置文件讀取類
net.sf.hibernate.collection.* Hibernate集合接口實現類,例如List,Set,Bag等等,Hibernate之所以要自行編寫集合接口實現類是為了支持lazy loading
net.sf.hibernate.connection.* 幾個數據庫連接池的Provider
net.sf.hibernate.dialect.* 支持多種數據庫特性,每個Dialect實現類代表一種數據庫,描述了該數據庫支持的數據類型和其它特點,例如是否有AutoIncrement,是否有Sequence,是否有分頁sql等等
net.sf.hibernate.eg.* Hibernate文檔中用到的例子
net.sf.hibernate.engine.* 這個包的類作用比較散
net.sf.hibernate.expression.* HQL支持的表達式
net.sf.hibernate.hq.* HQL實現
net.sf.hibernate.id.* ID生成器
net.sf.hibernate.impl.* 最核心的包,一些重要接口的實現類,如果Session,SessionFactory,Query等
net.sf.hibernate.jca.* JCA支持,把Session包裝為支持JCA的接口實現類
net.sf.hibernate.jmx.* 我不懂JMX,只知道JMX是用來編寫App Server的管理程序的,大概是JMX部分接口的實現,使得App Server可以通過JMX接口管理Hibernate
net.sf.hibernate.loader.* 也是很核心的包,主要是生成sql語句的
net.sf.hibernate.lob.* Blob和Clob支持
net.sf.hibernate.mapping.* hbm文件的屬性實現
net.sf.hibernate.metadata.* PO的Meta實現
net.sf.hibernate.odmg.* ODMG是一個ORM標準,這個包是ODMG標準的實現類
net.sf.hibernate.persister.* 核心包,實現持久對象和表之間的映射
net.sf.hibernate.proxy.* Proxy和Lazy Loading支持
net.sf.hibernate.ps.* 該包是PreparedStatment Cache
net.sf.hibernate.sql.* 生成JDBC sql語句的包
net.sf.hibernate.test.* 測試類,你可以用junit來測試Hibernate
net.sf.hibernate.tool.hbm2ddl.* 用hbm配置文件生成DDL
net.sf.hibernate.transaction.* Hibernate Transaction實現類
net.sf.hibernate.type.* Hibernate中定義的持久對象的屬性的數據類型
net.sf.hibernate.util.* 一些工具類,作用比較散
net.sf.hibernate.xml.* XML數據綁定
14. 緩存管理
Hibernate 中提供了兩級Cache,第一級別的緩存是Session級別的緩存,它是屬于事務范圍的緩存。這一級別的緩存由hibernate管理的,一般情況下無需進行干預;第二級別的緩存是SessionFactory級別的緩存,它是屬于進程范圍或群集范圍的緩存。這一級別的緩存可以進行配置和更改,并且可以動態加載和卸載。 Hibernate還為查詢結果提供了一個查詢緩存,它依賴于第二級緩存。
1. 一級緩存和二級緩存的比較:第一級緩存 第二級緩存 存放數據的形式 相互關聯的持久化對象 對象的散裝數據 緩存的范圍 事務范圍,每個事務都有單獨的第一級緩存進程范圍或集群范圍,緩存被同一個進程或集群范圍內的所有事務共享 并發訪問策略由于每個事務都擁有單獨的第一級緩存,不會出現并發問題,無需提供并發訪問策略由于多個事務會同時訪問第二級緩存中相同數據,因此必須提供適當的并發訪問策略,來保證特定的事務隔離級別 數據過期策略沒有提供數據過期策略。處于一級緩存中的對象永遠不會過期,除非應用程序顯式清空緩存或者清除特定的對象必須提供數據過期策略,如基于內存的緩存中的對象的最大數目,允許對象處于緩存中的最長時間,以及允許對象處于緩存中的最長空閑時間 物理存儲介質內存內存和硬盤。對象的散裝數據首先存放在基于內在的緩存中,當內存中對象的數目達到數據過期策略中指定上限時,就會把其余的對象寫入基于硬盤的緩存中。緩存的軟件實現 在Hibernate的Session的實現中包含了緩存的實現由第三方提供,Hibernate僅提供了緩存適配器(CacheProvider)。用于把特定的緩存插件集成到Hibernate中。啟用緩存的方式只要應用程序通過Session接口來執行保存、更新、刪除、加載和查詢數據庫數據的操作,Hibernate就會啟用第一級緩存,把數據庫中的數據以對象的形式拷貝到緩存中,對于批量更新和批量刪除操作,如果不希望啟用第一級緩存,可以繞過Hibernate API,直接通過JDBC API來執行指操作。用戶可以在單個類或類的單個集合的粒度上配置第二級緩存。如果類的實例被經常讀但很少被修改,就可以考慮使用第二級緩存。只有為某個類或集合配置了第二級緩存,Hibernate在運行時才會把它的實例加入到第二級緩存中。 用戶管理緩存的方式第一級緩存的物理介質為內存,由于內存容量有限,必須通過恰當的檢索策略和檢索方式來限制加載對象的數目。Session的evit()方法可以顯式清空緩存中特定對象,但這種方法不值得推薦。 第二級緩存的物理介質可以是內存和硬盤,因此第二級緩存可以存放大量的數據,數據過期策略的maxElementsInMemory屬性值可以控制內存中的對象數目。管理第二級緩存主要包括兩個方面:選擇需要使用第二級緩存的持久類,設置合適的并發訪問策略:選擇緩存適配器,設置合適的數據過期策略。
2. 一級緩存的管理: 當應用程序調用Session的save()、update()、savaeOrUpdate()、get()或load(),以及調用查詢接口的 list()、iterate()或filter()方法時,如果在Session緩存中還不存在相應的對象,Hibernate就會把該對象加入到第一級緩存中。當清理緩存時,Hibernate會根據緩存中對象的狀態變化來同步更新數據庫。 Session為應用程序提供了兩個管理緩存的方法: evict(Object obj):從緩存中清除參數指定的持久化對象。 clear():清空緩存中所有持久化對象。
3. 二級緩存的管理:
3.1. Hibernate的二級緩存策略的一般過程如下:
1) 條件查詢的時候,總是發出一條select * from table_name where …. (選擇所有字段)這樣的SQL語句查詢數據庫,一次獲得所有的數據對象。
2) 把獲得的所有數據對象根據ID放入到第二級緩存中。
3) 當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,如果配置了二級緩存,那么從二級緩存中查;查不到,再查詢數據庫,把結果按照ID放入到緩存。
4) 刪除、更新、增加數據的時候,同時更新緩存。
Hibernate的二級緩存策略,是針對于ID查詢的緩存策略,對于條件查詢則毫無作用。為此,Hibernate提供了針對條件查詢的Query Cache。
3.2. 什么樣的數據適合存放到第二級緩存中? 1 很少被修改的數據 2 不是很重要的數據,允許出現偶爾并發的數據 3 不會被并發訪問的數據 4 參考數據,指的是供應用參考的常量數據,它的實例數目有限,它的實例會被許多其他類的實例引用,實例極少或者從來不會被修改。
3.3. 不適合存放到第二級緩存的數據? 1 經常被修改的數據 2 財務數據,絕對不允許出現并發 3 與其他應用共享的數據。
3.4. 常用的緩存插件 Hibernater 的二級緩存是一個插件,下面是幾種常用的緩存插件:
EhCache:可作為進程范圍的緩存,存放數據的物理介質可以是內存或硬盤,對Hibernate的查詢緩存提供了支持。
OSCache:可作為進程范圍的緩存,存放數據的物理介質可以是內存或硬盤,提供了豐富的緩存數據過期策略,對Hibernate的查詢緩存提供了支持。
SwarmCache:可作為群集范圍內的緩存,但不支持Hibernate的查詢緩存。
JBossCache:可作為群集范圍內的緩存,支持事務型并發訪問策略,對Hibernate的查詢緩存提供了支持。
3.5. 配置二級緩存的主要步驟:
1) 選擇需要使用二級緩存的持久化類,設置它的命名緩存的并發訪問策略。這是最值得認真考慮的步驟。
2) 選擇合適的緩存插件,然后編輯該插件的配置文件。
轉載于:https://my.oschina.net/bluesroot/blog/222586
總結
以上是生活随笔為你收集整理的Hibernate面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 待删除未删除 问题解决
- 下一篇: IP别名和网卡绑定