2019年Java面試題(十六) Hibernate 2019-04-27

1. list,iterate區(qū)別

? 使用list()方法獲取查詢結(jié)果,每次發(fā)出一條查詢語(yǔ)句,獲取全部數(shù)據(jù)

? 使用iterate()方法獲取查詢結(jié)果,先發(fā)出一條SQL 語(yǔ)句用來(lái)查詢滿足條件數(shù)據(jù)的id,然后依次按這些id 查詢記錄,也就是要執(zhí)行N+1 條SQL 語(yǔ)句(N 為符合條件的記錄數(shù))

? list()方法將不會(huì)在緩存中讀取數(shù)據(jù),它總是一次性的從數(shù)據(jù)庫(kù)中直接查詢所有符合條件的數(shù)據(jù),同時(shí)將獲取的數(shù)據(jù)寫入緩存

? iterate()方法則是獲取了符合條件的數(shù)據(jù)的id 后,首先根據(jù)id 在緩存中尋找符合條件的數(shù)據(jù),若緩存中無(wú)符合條件的數(shù)據(jù),再到數(shù)據(jù)庫(kù)中查詢

2. 如何優(yōu)化Hibernate?

1).使用雙向一對(duì)多關(guān)聯(lián),不使用單向一對(duì)多

2).靈活使用單向一對(duì)多關(guān)聯(lián)

3).不用一對(duì)一,用多對(duì)一取代

4).配置對(duì)象緩存,不使用集合緩存

5).一對(duì)多集合使用Bag,多對(duì)多集合使用Set

6). 繼承類使用顯式多態(tài)

7). 表字段要少,表關(guān)聯(lián)不要怕多,有二級(jí)緩存撐腰

3. Hibernate 核心接口session介紹

1、作用:提供基本的保存,刪除,更新,和加載Java對(duì)象

2、什么是清理緩存:

Session能夠在某些時(shí)間點(diǎn),按照緩存中對(duì)象的變化來(lái)執(zhí)行相關(guān)的SQL語(yǔ)句,來(lái)同步更新數(shù)據(jù)庫(kù),這一過程別稱為清理緩存(flush)

3、SessionFactory是線程安全的(可以多個(gè)對(duì)象共用同一個(gè)對(duì)象)。而Session不是線程安全的。

為了解決Session線程不安全我們采用ThreadLocal方案。

ThreadLocal 模式的解決方案:

ThreadLocal并不是一個(gè)線程的本地實(shí)現(xiàn),也就是說(shuō)它不是一個(gè)Thread,而是Thread local variable(線程局部變量)。它的作用就是為每一個(gè)使用這個(gè)變量的線程提供一個(gè)變量的副本,并且每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會(huì)和其它線程的副本沖突。

ThreadLocal模式實(shí)例代碼:

public void getSession() {

Configuration cfg = new Configuration().configure();

SessionFactory sf = cfg.buildSessionFactory();

session = sf.openSession();

}

//創(chuàng)建ThreadLocal對(duì)象

private static final ThreadLocal threadLodacl = new ThreadLocal();

public void getSession() {

Configuration cfg = new Configuration().configure();

SessionFactory sf = cfg.buildSessionFactory();

//session = sf.openSession();

//解決session線程非安全的方式

this.session = (Session) threadLodacl.get();

if(session == null){

this.session = sf.openSession();

threadLodacl.set(this.session);

}

}

4.獲取session的兩種方式介紹

1、 getCurrentSession創(chuàng)建的Session會(huì)綁定到當(dāng)前線程,而openSession不會(huì)

2、 getCurrentSession創(chuàng)建的Session會(huì)在事務(wù)回滾或者事務(wù)提交后自動(dòng)關(guān)閉,而openSession創(chuàng)建的必須手動(dòng)關(guān)閉(調(diào)用Session的cloe()方法)

5. Hibernate操作的對(duì)象有三種狀態(tài)

1、瞬時(shí)狀態(tài)(Transient)/臨時(shí)。2.、持久化狀態(tài)(persistent)。3、托管狀態(tài)(detached)/游離狀態(tài)

1、當(dāng)一個(gè)對(duì)象通過new 新創(chuàng)建的時(shí)候就是瞬時(shí)狀態(tài)

? ? 瞬時(shí)狀態(tài)下對(duì)象的主鍵沒有值,也沒有納入session的管理,數(shù)據(jù)庫(kù)表中也沒有對(duì)應(yīng)的記錄,當(dāng)我們調(diào)用save等相關(guān)的其他方法是則進(jìn)入了持久化狀態(tài),

2、持久化狀態(tài)下對(duì)象納入了session管理中,對(duì)象標(biāo)示符有值。Hibernate保證在同一個(gè)session實(shí)例的緩存中數(shù)據(jù)庫(kù)中的一條記錄只對(duì)應(yīng)唯一的一個(gè)持久化對(duì)象。session在清理緩存時(shí)會(huì)根據(jù)持久化對(duì)象的屬性變化會(huì)同步更新數(shù)據(jù)庫(kù)。當(dāng)session關(guān)閉后持久化狀態(tài)就會(huì)變成托管狀態(tài)。當(dāng)持久化對(duì)象調(diào)用delete方法就由持久化變成了移除狀態(tài)

3、托管狀態(tài)下的特點(diǎn):對(duì)象不處于session的管理中。但他曾經(jīng)與某個(gè)持久化上下文發(fā)生過關(guān)聯(lián)(session),對(duì)象標(biāo)示符有值,數(shù)據(jù)庫(kù)可能存在與之相對(duì)的記錄。Hibernate不能夠保證托管狀態(tài)下的數(shù)據(jù)和數(shù)據(jù)庫(kù)中的數(shù)據(jù)同步更新。

4、臨時(shí)和游離狀態(tài)下的對(duì)象特點(diǎn):等待垃圾回收,

6. Hibernate有哪幾種查詢數(shù)據(jù)的方式

? ? ? (1)導(dǎo)航對(duì)象圖查詢

? ? ? (2)OID查詢

? ? ? (3)HQL

? ? ? (4)QBC

? ? ? (5)本地SQL

7. Hibernate優(yōu)化

1、避免or操作

where 子句包含or 操作,執(zhí)行時(shí)不使用索引

可以使用in條件來(lái)替換

2、避免使用not

where 子句包含not 關(guān)鍵字,執(zhí)行時(shí)該字段的索引失效

使用比較運(yùn)算符替換not

3、避免like的特殊形式

查詢時(shí),盡可能少使用like

4、避免having子句

盡可能在where 子句中指定條件

5、避免使用distinct

在不要求或允許冗余時(shí),應(yīng)避免使用distinct

8. 什么是懶加載 懶加載用什么技術(shù)實(shí)現(xiàn),如何解決session關(guān)閉導(dǎo)致的懶加載問題 解決的方案有缺點(diǎn)嗎

懶加載就是延遲加載,采用代理技術(shù)實(shí)現(xiàn),采用openSessionInViewFilter,openSessionInViewFilter其實(shí)上就是一個(gè)過濾器頁(yè)面打開時(shí)開啟session,頁(yè)面訪問結(jié)束時(shí)關(guān)閉session

當(dāng)訪問用戶過多,而且網(wǎng)速過慢的時(shí)候,會(huì)擠爆系統(tǒng)

事務(wù)擴(kuò)大了 加鎖導(dǎo)致資源等待時(shí)間過長(zhǎng)

session范圍變大? 如果加載頁(yè)面的時(shí)間過長(zhǎng) 如網(wǎng)速比較慢? session內(nèi)存時(shí)間過長(zhǎng) 導(dǎo)致系統(tǒng)性能下載

數(shù)據(jù)庫(kù)連接不能及時(shí)釋放

9. hibernate核心類

congfigeration負(fù)責(zé)管理配置信息

sessionfactory負(fù)責(zé)創(chuàng)建出session

session負(fù)責(zé)調(diào)用持久化方法

Transaction 負(fù)責(zé)事務(wù)管理

query為查詢接口

10. hibernate抓取策略

Hibernate的 抓取策略有四種

1、 join? ? ? ? 連接抓取 它是通過select語(yǔ)句使用外連接來(lái)加載實(shí)體或者集合? 懶加載會(huì)失效--同等于mybatis中的嵌套結(jié)果

2、 select? ? 查詢抓取 它是通過發(fā)送一條select語(yǔ)句抓取當(dāng)前對(duì)象關(guān)聯(lián)的實(shí)體或者集合 一條查自己 一條抓關(guān)聯(lián)數(shù)據(jù)

3、 subselect? 子查詢抓取 發(fā)送一條select語(yǔ)句查詢出關(guān)聯(lián)的實(shí)體或者集合,然后通過子查詢in完成

4、 batch-size? 批量抓取

11. hibernate 的原理? ? ? ? ?

1. 讀取并解析配置文件

2. 讀取并解析映射信息,創(chuàng)建SessionFactory

3. 打開Sesssion

4. 創(chuàng)建事務(wù)Transation

5. 持久化操作

6. 提交事務(wù)

7. 關(guān)閉Session

8. 關(guān)閉SesstionFactory

12. Hibernate 的session.save()與session.saveOrUpdate()的區(qū)別?

1.save()方法,調(diào)用save 方法時(shí),首先會(huì)在session 緩存中查找保存對(duì)象如果實(shí)體對(duì)象已經(jīng)處于Persient 狀態(tài),直接返回;否則并將保存至數(shù)據(jù)庫(kù),對(duì)象變?yōu)槌志脿顟B(tài)。

2.saveOrUpdate()方法:和save 方法一樣首先在session 緩存中查找,判斷對(duì)象是否為為保存狀態(tài),如果對(duì)象處于Persient,不執(zhí)行操作,處于Transient 執(zhí)行save 操作,處于Detached 調(diào)用saveOrUpdate 將對(duì)象與session 重新關(guān)聯(lián)(簡(jiǎn)單的說(shuō)就是該方法會(huì)先看該對(duì)象是否已經(jīng)存在,如果已經(jīng)存在就更新,否則新增保存),如果此時(shí)saveOrUpdate 的對(duì)象與另一個(gè)與Session 關(guān)聯(lián)的對(duì)象持有相同的持久化標(biāo)識(shí)則拋出相同的標(biāo)識(shí)符異常。

13. Hibernate 中sedssion.get()與session.load()的區(qū)別?

Session.load/get 方法均可以根據(jù)指定的實(shí)體類和id 從數(shù)據(jù)庫(kù)讀取記錄,并返回與之對(duì)

應(yīng)的實(shí)體對(duì)象。其區(qū)別在于:

1) 如果未能發(fā)現(xiàn)符合條件的記錄, get 方法返回null , 而load 方法會(huì)拋出一個(gè)

ObjectNotFoundException。

2) load 支持延遲加載,get 不支持

3) load 方法可返回實(shí)體的代理類實(shí)例,而get 方法永遠(yuǎn)直接返回實(shí)體類。

4) load 方法可以充分利用內(nèi)部緩存和二級(jí)緩存中的現(xiàn)有數(shù)據(jù),get 方法則僅僅在內(nèi)部緩存

中進(jìn)行數(shù)據(jù)查找,如沒有發(fā)現(xiàn)對(duì)應(yīng)數(shù)據(jù),將越過二級(jí)緩存,直接調(diào)用SQL 完成數(shù)據(jù)讀取。

14. 介紹下hibernate

Hibernate 是一個(gè)開放源代碼Java 語(yǔ)言下的對(duì)象關(guān)系映射解決方案。它為面向?qū)ο蟮念I(lǐng)域模型到傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)的映射,提供了一個(gè)使用方便的框架。Hibernate 也是目前Java開發(fā)中最為流行的數(shù)據(jù)庫(kù)持久層框架。將軟件開發(fā)人員從大量相同的數(shù)據(jù)持久層相關(guān)編程工作中解放出來(lái),Hibernate 不僅負(fù)責(zé)從Java 類到數(shù)據(jù)庫(kù)表的映射(還包括從Java 數(shù)據(jù)類型到SQL 數(shù)據(jù)類型的映射),還提供了面向?qū)ο蟮臄?shù)據(jù)查詢檢索機(jī)制,從而極大地縮短的手動(dòng)處理SQL 和JDBC 上的開發(fā)時(shí)間。

15. Hibernate 中的HQL 和criteria 的區(qū)別?

1.QBC(Query by Criteria)查詢對(duì)查詢條件進(jìn)行了面向?qū)ο蠓庋b,符合編程人員的思維方式;

2.HQL(Hibernate Query Language)查詢提供了更加豐富的和靈活的查詢特性,在涵蓋

Criteria 查詢的所有功能的前提下,提供了類似標(biāo)準(zhǔn)SQL 語(yǔ)句的查詢方式,同時(shí)也

提供了更加面向?qū)ο蟮姆庋b。

16. 介紹hibernate 延持加載屬性

Hibernate 通過lazy 來(lái)指定加載策略,一般值為true 或false,。設(shè)為flase 表示立即加載,true 表過延遲加載。

17. 列舉你接觸過的框架,說(shuō)明特點(diǎn)和原理

Hibernate 特點(diǎn):

1. 基于JDBC 的主流持久化框架,是一個(gè)優(yōu)秀的ORM 實(shí)現(xiàn),對(duì)JDBC 訪問數(shù)據(jù)庫(kù)的代碼做了封裝,大大簡(jiǎn)化了數(shù)據(jù)訪問層繁瑣的重復(fù)性代碼。

2. hibernate 使用Java 反射機(jī)制,而不是字節(jié)碼增強(qiáng)程序來(lái)實(shí)現(xiàn)透明性。

3. hibernate 的性能非常好,因?yàn)樗莻€(gè)輕量級(jí)框架。映射的靈活性很出色。它支持各種關(guān)系數(shù)據(jù)庫(kù),從一對(duì)一到多對(duì)多的各種復(fù)雜關(guān)系。

Spring 特點(diǎn):

Spring 框架的主要優(yōu)勢(shì)之一低侵入式的架構(gòu)思想,實(shí)現(xiàn)了IOC 容器。另外一個(gè)AOP 的編程也在很多應(yīng)用場(chǎng)合下地位較重。提供了對(duì)各種不同類型框架的支持,如:Web 容器、持入層、事務(wù)層、其它J2EE 組件等。

18. Ibatis 框架和Hibernate 框架各有什么特點(diǎn)?

19. 為什么要用ORM? 和JDBC 有何不一樣?

orm 是一種思想,就是把object 對(duì)象轉(zhuǎn)變成數(shù)據(jù)庫(kù)中的記錄,或者把數(shù)據(jù)庫(kù)中的記錄轉(zhuǎn)變成object 對(duì)象,我們可以用jdbc 來(lái)實(shí)現(xiàn)這種思想,orm 的思想本質(zhì)就是建立是JDBC 上,對(duì)JDBC 的一種封裝,這種封裝可以省去了直接使用jdbc 的繁瑣細(xì)節(jié),提高了開發(fā)效率,現(xiàn)在用的較多的ORM 工具很多,一般我們公司采用的ORM 框架主要有hibernate 和MyBatis。當(dāng)然也聽說(shuō)一些其他orm 工具,如toplink,ojb 等。

20. 簡(jiǎn)述Hibernate 和JDBC 的優(yōu)缺點(diǎn)?

1、封裝了jdbc,簡(jiǎn)化了很多重復(fù)性代碼。

2、簡(jiǎn)化了DAO 層編碼工作,使開發(fā)更對(duì)象化了。

3、移植性好,支持各種數(shù)據(jù)庫(kù),如果換個(gè)數(shù)據(jù)庫(kù)只要在配置文件中變換配置就可以了,不用改變hibernate 代碼。

4、支持透明持久化,因?yàn)閔ibernate 操作的是純粹的(pojo)java 類,沒有實(shí)現(xiàn)任何接口,沒有侵入性。

21. 寫Hibernate 的一對(duì)多和多對(duì)一雙向關(guān)聯(lián)的orm 配置?

1、 配置一對(duì)多

<!-- 部門對(duì)員工的一對(duì)多配置-->

<set name="employees" inverse="true" cascade="delete">

<key column="deptid"></key>

<one-to-many class="com.tsinghua.manager.vo.EmployeeVO"/>

</set>

2、 多對(duì)一

<!-- 員工對(duì)部門的多對(duì)一配置column 指定外鍵-->

<many-to-one name="department" class="com.tsinghua.manager.vo.DepartmentVO" column="deptid" />

22. Hibernate 對(duì)象有幾種狀態(tài)?如何轉(zhuǎn)換

共3 種狀態(tài),分別是:Transient 狀態(tài)(瞬時(shí))、Persient 狀態(tài)(持久)、Detached(脫管狀態(tài))狀態(tài)。

23. Hibernate 中有幾種關(guān)系映射

主要有單向一對(duì)一、單向一對(duì)多、單向多對(duì)一、單向多對(duì)多、雙向一對(duì)一、雙向一對(duì)多、雙向多對(duì)多

24. 談?wù)凥ibernate的理解,一級(jí)和二級(jí)緩存的作用,在項(xiàng)目中Hibernate都是怎么使用緩存的

一級(jí)緩存為session基本的緩存,是內(nèi)置的不能卸載。一個(gè)Session做了一個(gè)查詢操作,它會(huì)把這個(gè)結(jié)果放在一級(jí)緩存中,如果短時(shí)間內(nèi)這個(gè)session又做了同一個(gè)操作,那么hibernate就直接從一級(jí)緩存中獲取數(shù)據(jù)。

二級(jí)緩存是SessionFactory的緩存,分為內(nèi)置緩存和外置緩存兩類。即查詢結(jié)果放在二級(jí)緩存中,如果同一個(gè)sessionFactory創(chuàng)建的某個(gè)session執(zhí)行了相同的操作,hibernate就會(huì)從二級(jí)緩存中獲取結(jié)果。適合放在二級(jí)緩存中的數(shù)據(jù)包括:很少被修改的數(shù)據(jù),不是很重要的數(shù)據(jù),允許出現(xiàn)偶偶并發(fā)的數(shù)據(jù),不會(huì)被并發(fā)訪問的數(shù)據(jù),參考數(shù)據(jù)。不適合放在二級(jí)緩存中的數(shù)據(jù):經(jīng)常被修改的數(shù)據(jù),財(cái)務(wù)數(shù)據(jù),絕對(duì)不允許出現(xiàn)并發(fā),與其他應(yīng)用共享的數(shù)據(jù)。

25. Hibernate session的load()和get()的區(qū)別?

1:如果你使用load方法,hibernate認(rèn)為該id對(duì)應(yīng)的對(duì)象(數(shù)據(jù)庫(kù)記錄)在數(shù)據(jù)庫(kù)中是一定存在的,所以它可以放心的使用,它可以放心的使用代理來(lái)延遲加載該對(duì)象。在用到對(duì)象中的其他屬性數(shù)據(jù)時(shí)才查詢數(shù)據(jù)庫(kù),但是萬(wàn)一數(shù)據(jù)庫(kù)中不存在該記錄,那沒辦法,只能拋異常,所說(shuō)的load方法拋異常是指在使用該對(duì)象的數(shù)據(jù)時(shí),數(shù)據(jù)庫(kù)中不存在該數(shù)據(jù)時(shí)拋異常,而不是在創(chuàng)建這個(gè)對(duì)象時(shí)。由于session中的緩存對(duì)于hibernate來(lái)說(shuō)是個(gè)相當(dāng)廉價(jià)的資源,所以在load時(shí)會(huì)先查一下session緩存看看該id對(duì)應(yīng)的對(duì)象是否存在,不存在則創(chuàng)建代理。所以如果你知道該id在數(shù)據(jù)庫(kù)中一定有對(duì)應(yīng)記錄存在就可以使用load方法來(lái)實(shí)現(xiàn)延遲加載。 對(duì)于get方法,hibernate會(huì)確認(rèn)一下該id對(duì)應(yīng)的數(shù)據(jù)是否存在,首先在session緩存中查找,然后在二級(jí)緩存中查找,還沒有就查數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)中沒有就返回null(網(wǎng)上有很多誤解以為get就馬上去數(shù)據(jù)庫(kù)查找根本不先查session那是不正確的,不想信你就去做下試驗(yàn)便知)。

2、“get()永遠(yuǎn)只返回實(shí)體類”,但實(shí)際上這是不正確的,get方法如果在session緩存中找到了該id對(duì)應(yīng)的對(duì)象,如果剛好該對(duì)象前面是被代理過的,如被load方法使用過,或者被其他關(guān)聯(lián)對(duì)象延遲加載過,那么返回的還是原先的代理對(duì)象,而不是實(shí)體類對(duì)象,如果該代理對(duì)象還沒有加載實(shí)體數(shù)據(jù)(就是id以外的其他屬性數(shù)據(jù)),那么它會(huì)查詢二級(jí)緩存或者數(shù)據(jù)庫(kù)來(lái)加載數(shù)據(jù),但是返回的還是代理對(duì)象,只不過已經(jīng)加載了實(shí)體數(shù)據(jù)。

3、再注重說(shuō)明get方法首先查詢session緩存,沒有的話查詢二級(jí)緩存,最后查詢數(shù)據(jù)庫(kù);反而load方法創(chuàng)建時(shí)首先查詢session緩存,沒有就創(chuàng)建代理,實(shí)際使用數(shù)據(jù)時(shí)才查詢二級(jí)緩存和數(shù)據(jù)庫(kù)。

總之對(duì)于get和load的根本區(qū)別,一句話,hibernate對(duì)于load方法認(rèn)為該數(shù)據(jù)在數(shù)據(jù)庫(kù)中一定存在,可以放心的使用代理來(lái)延遲加載,如果在使用過程中發(fā)現(xiàn)了問題,只能拋異常;而對(duì)于get方法,hibernate一定要獲取到真實(shí)的數(shù)據(jù),否則返回null。

26. 各種關(guān)聯(lián)關(guān)系下的lazy懶加載區(qū)別?

1、 one-to-one懶加載

一對(duì)一的懶加載并不常用,因?yàn)閼屑虞d的目的是為了減少與數(shù)據(jù)庫(kù)的交互,從而提高執(zhí)行效率,而在一對(duì)一關(guān)系中,主表中的每一條數(shù)據(jù)只對(duì)應(yīng)從表的一條數(shù)據(jù)庫(kù),就算都查詢也不會(huì)增加多少交互的成本,而且主表不能有contrained=true,所以主表是不能懶加載的。但是從表可以有。實(shí)現(xiàn)此種懶加載必須在從對(duì)象這邊同時(shí)滿足三個(gè)條件:

a)lazy!=false(lazy的屬性有三個(gè)選項(xiàng)分別為:no-proxy、false和proxy)

b)Constrained = true ;

c)fetch=select。

注:當(dāng)fetch設(shè)置為join時(shí),懶加載就會(huì)失效。因?yàn)閒etch的作用是抓取方式,他有兩個(gè)值分別為select和join,默認(rèn)值為select。即在設(shè)為join時(shí),他會(huì)直接將從表信息以join方式查詢到而不是再次使用select查詢,這樣導(dǎo)致了懶加載的失效。

2、 one-to-many懶加載

與one-to-one關(guān)聯(lián)不同,對(duì)one-to-many而言,主表的每一條屬性都會(huì)對(duì)應(yīng)從表的多條數(shù)據(jù),這個(gè)時(shí)候懶加載就顯得非常有效了。比如一個(gè)部門里面有多個(gè)員工,如果沒有懶加載,每查詢這個(gè)部門的時(shí)候都會(huì)查詢出多個(gè)員工,這會(huì)大大增加與數(shù)據(jù)庫(kù)交互的成本。所以Hbernate默認(rèn)的是加入懶加載的。這就是查詢集合屬性的時(shí)候返回的是一個(gè)PersistentIndexed*類型對(duì)象的原因。該對(duì)象其實(shí)就是一個(gè)代理對(duì)象。當(dāng)然,可以在映射文件中通過將lazy屬性設(shè)為假來(lái)禁用。

Hibernate默認(rèn)對(duì)one-to-many就是使用的懶加載,但用戶也可以取消懶加載操作:

一:設(shè)置lazy=”false”;

二:設(shè)置fetch=”join”.

實(shí)現(xiàn)此種懶加載必須在從對(duì)象這邊同時(shí)滿足兩個(gè)條件:

1、lazy!=false(lazy的屬性有三個(gè)選項(xiàng)分別為:no-proxy、false和proxy)

2、fetch=select。

3、 many-to-one懶加載

此關(guān)聯(lián)關(guān)系的懶加載和one-to-one的懶加載一樣都是可要可不要的,因?yàn)閷?duì)執(zhí)行效率的提高都不是非常明顯。雖然多對(duì)一與一對(duì)一關(guān)系方式相同,但是在Hibernate中多對(duì)一時(shí),默認(rèn)是進(jìn)行懶加載的。另外有一點(diǎn)需要注意的是懶加載并不會(huì)區(qū)分集合屬性里面是否有值,即使是沒有值,他依然會(huì)使用懶加載。實(shí)現(xiàn)此種懶加載必須在從對(duì)象這邊同時(shí)滿足兩個(gè)條件

1、lazy!=false(lazy的屬性有三個(gè)選項(xiàng)分別為:no-proxy、false和proxy)

2、fetch=select

4、 many-to-many懶加載

此關(guān)聯(lián)關(guān)系的懶加載和one-to-many的懶加載一樣對(duì)程序的執(zhí)行效率的提高都是非常明顯的。

實(shí)現(xiàn)此種懶加載必須在從對(duì)象這邊同時(shí)滿足兩個(gè)條件:

1、lazy!=false(lazy的屬性有三個(gè)選項(xiàng)分別為:no-proxy、false和proxy)

2、fetch=select

能夠懶加載的對(duì)象都是被改過的代理對(duì)象,當(dāng)相應(yīng)的對(duì)象沒有關(guān)閉時(shí),訪問這些懶加載對(duì)象的屬性(getId和getClass除外)Hibernate會(huì)初始化這些代理,或用hibernate.initalize(proxy)來(lái)初始化代理對(duì)象;當(dāng)關(guān)閉session后在訪問懶加載的對(duì)象就會(huì)出現(xiàn)異常。

27. 類(Class)的延遲加載:

◆設(shè)置<class>標(biāo)簽中的lazy=”true”,或是保持默認(rèn)(即不配置lazy屬性)

◆ 如果lazy的屬性值為true,那么在使用load方法加載數(shù)據(jù)時(shí),只有確實(shí)用到數(shù)據(jù)的時(shí)候才會(huì)發(fā)出sql語(yǔ)句;這樣有可能減少系統(tǒng)的開銷。

注意:在class標(biāo)簽上配置的lazy屬性不會(huì)影響到關(guān)聯(lián)對(duì)象!


28. Hiberbate 優(yōu)化方法有那些?

【參考答案】

1) 盡量使用many-to-one,避免使用one-to-many

2) 靈活使用單向one-to-many

3) 不用一對(duì)一,使用多對(duì)一代替一對(duì)一

4) 配置對(duì)象緩存,不使用集合緩存

5) 一對(duì)多使用Bag 多對(duì)一使用Set

6) 繼承使用顯示多態(tài)HQL:from object polymorphism="exlicit" 避免查處所有對(duì)象

7) 消除大表,使用二級(jí)緩存

29. 如何設(shè)置Hibernate 二級(jí)緩存

1、首先要打開二級(jí)緩存,在hibernate.cfg.xml 中添加如下配置:<property name="hibernate.cache.use_second_level_cache">true</property>

2、Hibernate 的二級(jí)緩存使用第三方的緩存工具來(lái)實(shí)現(xiàn),所以我們需要指定Hibernate使用哪個(gè)緩存工具。如下配置指定Hibernate 使用EhCache 緩存工具。

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider

</property>

3、 Hibernate 在默認(rèn)情況下并不會(huì)對(duì)所有實(shí)體對(duì)象進(jìn)行緩存,所以,我們需要指定緩存哪些對(duì)象,在實(shí)體對(duì)象的映射文件中(相應(yīng)的<class>標(biāo)簽內(nèi)部),添加如下配置:<cache usage="read-only"/>usage="read-only"是“只讀”緩存策略。

30. Hibernate 有哪幾種查詢數(shù)據(jù)的方法?

【參考答案】

hibernate 查詢有三種方式:HQL 查詢、結(jié)構(gòu)化SQL 查詢、QBC 查詢

31. 介紹hibernate 延持加載屬性

【參考答案】Hibernate 通過lazy 來(lái)指定加載策略,一般值為true 或false,。設(shè)為flase 表示立即加載,true 表過延遲加載。

32. 簡(jiǎn)述Hibernate 和JDBC 的優(yōu)缺點(diǎn)? 如何書寫一個(gè)one to many 配置文件

1、封裝了jdbc,簡(jiǎn)化了很多重復(fù)性代碼。

2、簡(jiǎn)化了DAO 層編碼工作,使開發(fā)更對(duì)象化了。

3、移植性好,支持各種數(shù)據(jù)庫(kù),如果換個(gè)數(shù)據(jù)庫(kù)只要在配置文件中變換配置就可以了,不用改變hibernate 代碼。

4、支持透明持久化,因?yàn)閔ibernate 操作的是純粹的(pojo)java 類,沒有實(shí)現(xiàn)任何接口,沒有侵入性。

33. Hibernate 對(duì)象有幾種狀態(tài)?如何轉(zhuǎn)換

共3 種狀態(tài),分別是:Transient 狀態(tài)(瞬時(shí))、Persient 狀態(tài)(持久)、Detached(脫管狀態(tài))狀態(tài)。

34. hibernate 有哪五個(gè)核心接口。

Configuration 接口,SessionFactory 接口,Session 接口,Transaction 接口,Query 和Criteria接口

35. Hibernate 中有幾種關(guān)系映射

主要有單向一對(duì)一、單向一對(duì)多、單向多對(duì)一、單向多對(duì)多、雙向一對(duì)一、雙向一對(duì)多、雙向多對(duì)多。

36. 什么是懶加載 懶加載用代理技術(shù)實(shí)現(xiàn)? 如何解決session關(guān)閉導(dǎo)致的懶加載問題 解決的方案有缺點(diǎn)嗎?

? 1 懶加載 真正需要數(shù)據(jù)的時(shí)候才向數(shù)據(jù)庫(kù)發(fā)送sql,比如調(diào)用load方法,不會(huì)發(fā)出sql,而在加載對(duì)象屬性時(shí)才發(fā)出了sql,實(shí)現(xiàn)了數(shù)據(jù)的延遲加載,get則不然

? 2 使用openSessionInView模式解決,實(shí)則是一個(gè)過濾器,保持session一直在view一直打開

? ? 1 session范圍擴(kuò)大,從dao擴(kuò)展到了其他的層,session所暫用的資源不能得到及時(shí)的釋放,效率下降

? ? 2 事務(wù)擴(kuò)大了

37. hibernate 實(shí)體的3種狀態(tài)?

? ? 1? 瞬時(shí)狀態(tài) :剛new出來(lái)的對(duì)象,與session沒關(guān)聯(lián),調(diào)用delete方法也會(huì)使對(duì)象進(jìn)入瞬時(shí)狀

? ? 2? 持久化狀態(tài):調(diào)用session的api,如save saveorupdate,load get進(jìn)入持久化狀態(tài),屬性的改變?cè)谑聞?wù)提交的時(shí)候同步數(shù)據(jù)庫(kù)

? ? 3? 脫管狀態(tài) :調(diào)用了session的clear或者close evit 都使對(duì)象脫離了session的管理,狀態(tài)發(fā)生改變不會(huì)影響到數(shù)據(jù)庫(kù)

38. hibernate 的原理步驟 核心類

答:?

1).讀取配置文件;

2).創(chuàng)建SessionFactory(安全);

3).創(chuàng)建session(不安全);

4).開啟事務(wù);

5).進(jìn)行Crud操作(save,update,saveOrUpdate,load,get方法);

6).提交事務(wù);

7).關(guān)閉session;

8).關(guān)閉SessionFactory;

核心類:

1).Configuration:讀取配置文件;

2).SessionFactory:通過Configuration的實(shí)例創(chuàng)建,是線程安全的;

3).Session:通過SessionFactory的實(shí)例創(chuàng)建,線程不安全;

4).Transaction:事務(wù)管理

39. hibernate 的經(jīng)驗(yàn) (如 大數(shù)據(jù)處理 性能優(yōu)化 有什么經(jīng)驗(yàn) 最佳實(shí)踐)

? ? ? 1 當(dāng)session關(guān)閉仍導(dǎo)致懶加載問題,可使用openSessionInView模式來(lái)解決

? ? ? 2 sql優(yōu)化九大原則

? ? ? 3 配置二級(jí)緩存EHCache

? ? ? 4 對(duì)于內(nèi)容較大的字段使用懶加載

? ? ? 5 api的正確使用,第一次使用list,之后使用iterbate

? ? ? 6 關(guān)聯(lián)優(yōu)化

? ? ? 7 項(xiàng)目上線后把hql的輸出關(guān)閉

? ? ? 8 大數(shù)據(jù)量的處理

? ? ? ? ? 摻入大數(shù)據(jù)

? ? ? ? ? 1 分批刷新,清除緩存

? ? ? ? ? 2 使用無(wú)狀態(tài)的session

? ? ? ? ? 3 更新 exeuteupdate

? ? ? ? ? 查詢: 分頁(yè)機(jī)制

? ? ? ? ? ? ? ? setFirstresult(起始位置) setMaxResult(一次取幾條)

? ? ? 9 session無(wú)法控制數(shù)量,導(dǎo)致緩存溢出

? ? ? 10 無(wú)法與第三方系統(tǒng)共存,否則緩存無(wú)法控制


40. 談?wù)凥ibernate與Ibatis的區(qū)別,哪個(gè)性能會(huì)更高一些

Ibatis相當(dāng)較為簡(jiǎn)單,容易上手,Hibernate比較復(fù)雜,門檻較高。如果系統(tǒng)需要處理數(shù)據(jù)量很大,性能要求很高,需要執(zhí)行高度優(yōu)化的sql語(yǔ)句才能達(dá)到性能要求,則此時(shí)Ibatis會(huì)比較好。

對(duì)不同數(shù)據(jù)庫(kù)支持方面Hibernate較好,因?yàn)镮batis需要修改的字段較多。另外Hibernate現(xiàn)已成為主流的o/r Mapping框架,開發(fā)效率高。

41. hibernate注解

答:1.@Entity

? ? ? ? @Table(name="表名")? 標(biāo)記為持久類映射

2.@Id @GeneratedValue? ? 主鍵生成機(jī)制

3.@ElementCollection? ? 集合映射

4.@OneToMany? ? 一對(duì)多

5.@ManyToMany? 多對(duì)多

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容