hibernate的工作原理
1.Hibernate 的初始化.
讀取Hibernate 的配置信息-〉創(chuàng)建Session Factory
1)創(chuàng)建Configeration類的實(shí)例梭冠。
它的構(gòu)造方法:將配置信息(Hibernate config.xml)讀入到內(nèi)存配名。
一個(gè)Configeration 實(shí)例代表Hibernate 所有Java類到Sql數(shù)據(jù)庫映射的集合唐断。
2)創(chuàng)建SessionFactory實(shí)例
把Configeration 對象中的所有配置信息拷貝到SessionFactory的緩存中。
SessionFactory的實(shí)例代表一個(gè)數(shù)據(jù)庫存儲員源俐东,創(chuàng)建后不再與Configeration 對象關(guān)聯(lián)。
緩存(cache):指Java對象的屬性(通常是一些集合類型的屬性--占用內(nèi)存空間。
SessionFactory的緩存中:Hibernate 配置信息耀盗。OR映射元數(shù)據(jù)氛雪。
緩存-大:重量級對象 蟹看摇:輕量級對象
3)調(diào)用SessionFactory創(chuàng)建Session的方法
1】用戶自行提供JDBC連接。
Connection con=dataSource.getConnection();
Session s=sessionFactory.openSession(con);
2】讓SessionFactory提供連接
Session s=sessionFactory.openSession();
4)通過Session 接口提供的各種方法來操縱數(shù)據(jù)庫訪問报亩。
Hibernate 的緩存體系
一級緩存:
Session 有一個(gè)內(nèi)置的緩存浴鸿,其中存放了被當(dāng)前工作單元加載的對象。
每個(gè)Session 都有自己獨(dú)立的緩存弦追,且只能被當(dāng)前工作單元訪問岳链。
二級緩存:
SessionFactory的外置的可插拔的緩存插件。其中的數(shù)據(jù)可被多個(gè)Session共享訪問劲件。
SessionFactory的內(nèi)置緩存:存放了映射元數(shù)據(jù)掸哑,預(yù)定義的Sql語句。
Hibernate 中Java對象的狀態(tài)
1.臨時(shí)狀態(tài) (transient)
特征:
1】不處于Session 緩存中
2】數(shù)據(jù)庫中沒有對象記錄
Java如何進(jìn)入臨時(shí)狀態(tài)
1】通過new語句剛創(chuàng)建一個(gè)對象時(shí)
2】當(dāng)調(diào)用Session 的delete()方法零远,從Session 緩存中刪除一個(gè)對象時(shí)苗分。
2.持久化狀態(tài)(persisted)
特征:
1】處于Session 緩存中
2】持久化對象數(shù)據(jù)庫中設(shè)有對象記錄
3】Session 在特定時(shí)刻會(huì)保持二者同步
Java如何進(jìn)入持久化狀態(tài)
1】Session 的save()把臨時(shí)-》持久化狀態(tài)
2】Session 的load(),get()方法返回的對象
3】Session 的find()返回的list集合中存放的對象
4】Session 的update(),saveOrupdate()使游離-》持久化
3.游離狀態(tài)(detached)
特征:
1】不再位于Session 緩存中
2】游離對象由持久化狀態(tài)轉(zhuǎn)變而來,數(shù)據(jù)庫中可能還有對應(yīng)記錄牵辣。
Java如何進(jìn)入持久化狀態(tài)-》游離狀態(tài)
1】Session 的close()方法
2】Session 的evict()方法摔癣,從緩存中刪除一個(gè)對象。提高性能纬向。少用择浊。
為什么要用:
1. 對JDBC訪問數(shù)據(jù)庫的代碼做了封裝,大大簡化了數(shù)據(jù)訪問層繁瑣的重復(fù)性代碼逾条。
2. Hibernate是一個(gè)基于JDBC的主流持久化框架琢岩,是一個(gè)優(yōu)秀的ORM實(shí)現(xiàn)。他很大程度的簡化DAO層的編碼工作
3. hibernate使用Java反射機(jī)制膳帕,而不是字節(jié)碼增強(qiáng)程序來實(shí)現(xiàn)透明性粘捎。
4. hibernate的性能非常好薇缅,因?yàn)樗莻€(gè)輕量級框架。映射的靈活性很出色攒磨。它支持各種關(guān)系數(shù)據(jù)庫泳桦,從一對一到多對多的各種復(fù)雜關(guān)系。
Hibernate是如何延遲加載?
1. Hibernate2延遲加載實(shí)現(xiàn):a)實(shí)體對象 b)集合(Collection)
2. Hibernate3 提供了屬性的延遲加載功能
當(dāng)Hibernate在查詢數(shù)據(jù)的時(shí)候娩缰,數(shù)據(jù)并沒有存在與內(nèi)存中灸撰,當(dāng)程序真正對數(shù)據(jù)的操作時(shí),對象才存在與內(nèi)存中拼坎,就實(shí)現(xiàn)了延遲加載浮毯,他節(jié)省了服務(wù)器的內(nèi)存開銷,從而提高了服務(wù)器的性能泰鸡。
3.Hibernate中怎樣實(shí)現(xiàn)類之間的關(guān)系?(如:一對多债蓝、多對多的關(guān)系)
類與類之間的關(guān)系主要體現(xiàn)在表與表之間的關(guān)系進(jìn)行操作,它們都市對對象進(jìn)行操作盛龄,我們程序中把所有的表與類都映射在一起饰迹,它們通過配置文件中的many-to-one、one-to-many余舶、many-to-many
說下Hibernate的緩存機(jī)制
1. 內(nèi)部緩存存在Hibernate中又叫一級緩存啊鸭,屬于應(yīng)用事物級緩存
2. 二級緩存:
a) 應(yīng)用及緩存
b) 分布式緩存
條件:數(shù)據(jù)不會(huì)被第三方修改、數(shù)據(jù)大小在可接受范圍匿值、數(shù)據(jù)更新頻率低赠制、同一數(shù)據(jù)被系統(tǒng)頻繁使用、非 關(guān)鍵數(shù)據(jù)
c) 第三方緩存的實(shí)現(xiàn)
////////一級緩存:session級的緩存也叫事務(wù)級的緩存挟憔,只緩存實(shí)體钟些,生命周期和session一致。不能對其進(jìn)行管理曲楚。
不用顯示的調(diào)用厘唾。
二級緩存:sessionFactory緩存,也叫進(jìn)程級的緩存龙誊,使用第3方插件實(shí)現(xiàn)的抚垃,也值緩存實(shí)體,生命周期和sessionFactory一致趟大,可以進(jìn)行管理鹤树。
首先配置第3放插件,我們用的是EHCache逊朽,在hibernate.cfg.xml文件中加入
true
在映射中也要顯示的調(diào)用罕伯,
二級緩存之查詢緩存:對普通屬性進(jìn)行緩存。如果關(guān)聯(lián)的表發(fā)生了修改叽讳,那么查詢緩存的生命周期也結(jié)束了追他。
在程序中必須手動(dòng)啟用查詢緩存:query.setCacheable(true)
Hibernate的查詢方式
Sql坟募、Criteria,object comptosition
Hql:
1、 屬性查詢
2邑狸、 參數(shù)查詢懈糯、命名參數(shù)查詢
3、 關(guān)聯(lián)查詢
4单雾、 分頁查詢
5赚哗、 統(tǒng)計(jì)函數(shù)
如何優(yōu)化Hibernate?
1.使用雙向一對多關(guān)聯(lián)硅堆,不使用單向一對多
2.靈活使用單向一對多關(guān)聯(lián)
3.不用一對一屿储,用多對一取代
4.配置對象緩存,不使用集合緩存
5.一對多集合使用Bag,多對多集合使用Set
6. 繼承類使用顯式多態(tài)
7. 表字段要少渐逃,表關(guān)聯(lián)不要怕多够掠,有二級緩存撐腰
.Hibernate有哪幾種查詢數(shù)據(jù)的方式
(1)導(dǎo)航對象圖查詢
(2)OID查詢
(3)HQL
(4)QBC
(5)本地SQL
load()和get()的區(qū)別
load加載方法:
Java代碼
Users user = (Users)session.load(Users.class, userId);
Users user = (Users)session.load(Users.class, userId);
get加載方法:
Java代碼
Users user = (Users)session.get(Users.class, userId);
Users user = (Users)session.get(Users.class, userId);
兩加載方法區(qū)別:
區(qū)別1:如果數(shù)據(jù)庫中,沒有userId的對象茄菊。如果通過get方法加載祖屏,則返回的是一個(gè)null;如果通過load加載买羞,則返回一個(gè)代理對象,如果后面代碼如果調(diào)用user對象的某個(gè)屬性(比如user.getPassword())會(huì)拋出異常:org.hibernate.ObjectNotFoundException雹食;
區(qū)別2:load支持延遲加載畜普,get不支持延遲加載。
也就是說:
Java代碼
Users user = (Users)session.load(Users.class, userId);
Users user = (Users)session.load(Users.class, userId);
這句代碼不會(huì)去執(zhí)行數(shù)據(jù)庫查詢群叶,只有用到user時(shí)才會(huì)去執(zhí)行數(shù)據(jù)庫查詢吃挑。
而:
Java代碼
Users user = (Users)session.get(Users.class, userId);
Users user = (Users)session.get(Users.class, userId);
則立即去執(zhí)行數(shù)據(jù)庫查詢。 所以Users user = (Users)session.load(Users.class, userId);不會(huì)執(zhí)行任何sql街立。
注意:
Java代碼
Users user = (Users)session.load(Users.class, userId);
System.out.println(user.getId());
Users user = (Users)session.load(Users.class, userId);
System.out.println(user.getId());
上面這2句代碼舶衬,不會(huì)去執(zhí)行數(shù)據(jù)庫操作。因?yàn)閘oad后會(huì)在hibernate的一級緩存里存放一個(gè)map對象赎离,該map的key就是userId的值逛犹,但是當(dāng)你getId()時(shí),它會(huì)去一級緩存里拿map的key值梁剔,而不去執(zhí)行數(shù)據(jù)庫查詢虽画。所以不會(huì)報(bào)任何錯(cuò)。不會(huì)執(zhí)行任何數(shù)據(jù)庫操作荣病。
hibernate的開發(fā)步驟:
開發(fā)步驟
1)搭建好環(huán)境
引入hibernate最小的jar包
準(zhǔn)備Hibernate.cfg.xml啟動(dòng)配置文件
2)寫實(shí)體類(pojo)
3)為實(shí)體類寫映射文件"User.hbm.xml"
在hibernate.cfg.xml添加映射的實(shí)體
4)創(chuàng)建庫表
5)寫測試類
獲得Configuration
創(chuàng)建SessionFactory
打開Session
開啟事務(wù)
使用session操作數(shù)據(jù)
提交事務(wù)
關(guān)閉資源
研究了兩天的 Hibernate码撰,看了很多資料,也拜讀了其關(guān)鍵類个盆,感覺自己有很多地方需要學(xué)習(xí)脖岛。比如說Hibernate的緩存機(jī)制是怎么實(shí)現(xiàn)的朵栖,Hibernate在封裝JDBC和JTA時(shí)都做了些什么,其ORM是怎么實(shí)現(xiàn)的等等柴梆。要弄清這些東西估計(jì)需要很長時(shí)間的摸索和積累陨溅,也只有在實(shí)際應(yīng)用中不斷加深對它們的理解了:)下面,我將最近兩天的收獲總結(jié)一下轩性,主要敘述一下Hibernate的基本工作原理声登。對于Hibernate的緩存機(jī)制、基于JDBC和JTA的事務(wù)處理及其ORM的實(shí)現(xiàn)等技術(shù)揣苏,以后慢慢再補(bǔ)吧悯嗓。
所謂Hibernate的基本工作原理,換言之卸察,也就是Hibernate大體的工作流程脯厨。在這里,我們仿照前面對Struts基本原理的闡述方法坑质,僅將其原理圖呈現(xiàn)給大家合武,詳細(xì)文字說明在此略過。
面試題: