關(guān)于Hibernate的一些學(xué)習(xí)心得總結(jié)
對于Hibernate剛剛學(xué)習(xí)了一周時(shí)間了,作為一名java初學(xué)者,也有點(diǎn)自己的感受想分享出來,如果這篇文章能有幸被大家看到,也僅供大家娛樂。如果有什么不足之處,歡迎大家多多指點(diǎn),多多批評。僅供參考,不喜勿噴。
前段時(shí)間剛學(xué)習(xí)了用JDBC來進(jìn)行java和數(shù)據(jù)庫的連接,來實(shí)現(xiàn)對數(shù)據(jù)的持久化操作和增刪改查,但是學(xué)習(xí)完的感受就是JDBC過于繁瑣,因?yàn)樗鼰o法直接面對對象,開發(fā)效率地,代碼又多,還重復(fù),完全不符合java面向?qū)ο蟮乃季S模式。Hibernate的誕生算是給java程序員很好地解決了這個(gè)問題,所以我們可以忘掉JDBC了,來看看Hibernate是如何實(shí)現(xiàn)java的持久化操作的。
Hibernate是一個(gè)優(yōu)秀的Java 持久化層解決方案,是當(dāng)今主流的對象—關(guān)系映射(ORM)工具。它的優(yōu)勢有三點(diǎn),第一:它是一個(gè)開發(fā)源代碼的對象關(guān)系映射框架;第二:對JDBC進(jìn)行了非常輕量級的對象封裝, 簡化了JDBC 繁瑣的編碼;第三:將JavaBean對象和數(shù)據(jù)庫的表建立對應(yīng)關(guān)系。ORM是持久化層的一種解決方案,它是將java中的類對象及相關(guān)屬性和相關(guān)類與數(shù)據(jù)庫中的表及表的屬性和鍵做相關(guān)的一一映射,來實(shí)現(xiàn)java對象和數(shù)據(jù)庫的聯(lián)系。下面我就來具體說說自己是如何學(xué)習(xí)Hibernate的。
一:hibernate入門
對于搭建項(xiàng)目框架編寫hibernate配置文件、實(shí)體映射文件我就不多說了。首先我們要先用Configuration接口來新建會話工廠,再從SessionFactory(會話工廠)里獲得會話實(shí)例(一般情況下,整個(gè)應(yīng)用只有唯一的一個(gè)SessionFactory,它應(yīng)該在應(yīng)用初始化時(shí)被創(chuàng)建),然后獲取Session實(shí)例,用Session可以操作數(shù)據(jù)庫和類中的對象,用Transaction接口的commit()和roolback()方法來提交事務(wù)和回滾事物,用Query來對數(shù)據(jù)庫實(shí)現(xiàn)查詢(用SQL或HQL)。另外在對數(shù)據(jù)進(jìn)行增刪改查操作時(shí),Hibernate中的實(shí)體對象有三種對象:瞬時(shí)狀態(tài),持久狀態(tài),游離狀態(tài)。狀態(tài)不同,實(shí)現(xiàn)方法也不相同。大家可以自己慢慢體會。
二:關(guān)聯(lián)映射
既然Hibernate是關(guān)系映射工具,必然存在many-to-one,one-to-many,雙向一對多,many-to-many關(guān)聯(lián)。要實(shí)現(xiàn)這些操作,首先實(shí)體之間要有關(guān)聯(lián)關(guān)系,即通過一個(gè)對象持有另一個(gè)對象的實(shí)例。而在數(shù)據(jù)庫的表中,表的主外鍵也能實(shí)現(xiàn)表與表的關(guān)聯(lián)關(guān)系。然后我們就要把這些關(guān)聯(lián)關(guān)系在映射文件(hbm.xml)中體現(xiàn)出來。many-to-one是many的一端應(yīng)持有one的一端的對象(引用),one-to-many是one的一端應(yīng)持有many端的對象集合,雙向一對多就是同時(shí)配置了單向的一對多和單向的多對一,多對多關(guān)聯(lián)則是將多對多轉(zhuǎn)換成兩個(gè)一對多,而且為中間表建立實(shí)體類及映射文件,兩個(gè)端點(diǎn)和中間端分別建立雙向一對多關(guān)聯(lián)。
三:HQL實(shí)用技術(shù)
Hibernate支持兩種主要的查詢方式。HQL(Hibernate Query Languge,Hibernate 查詢語言)查詢是一種面向?qū)ο蟮牟樵冋Z言,其中沒有表和字段的概念,只有類、對象和屬性的概念,HQL 是應(yīng)用較為廣泛的方式。Criteria 查詢又稱為“對象查詢”,它用面向?qū)ο蟮姆绞綄?gòu)造查詢的過程做了封裝。
HQL相比與SQL更符合java面向?qū)ο笏季S,也更加簡單。HQL中沒有表和字段的概念,只有類、對象和屬性的概念。例如你要查詢名字中帶有“Spring”的一本書,SQL:select * from books where book_name like ‘%Spring%' HQL :from Book b where b.name like 'Spring%' SQL中用到的是數(shù)據(jù)庫中的表名books和字段book_name,而HQL中用到的是Book類名和Book的name屬性,而Book類和books表又是映射關(guān)系,所以相當(dāng)于實(shí)現(xiàn)了數(shù)據(jù)庫的操作。是不是更加形象呢?
Criteria 查詢用的比較少,從Session中獲取Criteria實(shí)例,設(shè)定限制方法(用到Restrictions常用的查詢條件)。相當(dāng)于把HQL語句轉(zhuǎn)化成一個(gè)個(gè)方法來實(shí)現(xiàn)查詢??醋约合埠冒?,反正我是覺得HQL更實(shí)用一些吧。
四:HQL中的延遲加載和Hibernate高速緩存
HQL和Criteria查詢過程中都會延遲加載,有人覺得這是Hibernate的一個(gè)缺陷,我覺得這更像是Hibernate的高明之處。在得到一個(gè)Session實(shí)例后,用Book為例,你用Session的get()方法得到一本Book,Book是主對象,而Book又有一個(gè)Type關(guān)聯(lián)對象,但是得到的Book對象不會加載Type關(guān)聯(lián)對象,只有在你需要用到Type關(guān)聯(lián)對象時(shí)才會強(qiáng)制加載Type關(guān)聯(lián)對象,具體來說就是關(guān)聯(lián)對象和關(guān)聯(lián)集合的默認(rèn)加載計(jì)劃是:延遲加載,即加載主對象時(shí)它們不會被立即加載,而是直到使用這些對象和集合時(shí)才發(fā)送SQL語句、獲取數(shù)據(jù)、初始化對象和集合,而主對象的屬性默認(rèn)是被立即加載的。當(dāng)然這種方式也是可以強(qiáng)制改變的,在用Criteria查詢時(shí),你可以在實(shí)體類的映射文件中來添加 lazy = “false” 來強(qiáng)制加載。不過不建議這種方式,因?yàn)闀斐刹槐匾馁Y源浪費(fèi),效率也極低。如果需要,我們可以在編寫代碼時(shí)強(qiáng)制加載效果會更好一些。
總之,這種延遲加載策略會簡化SQL語句,提高查詢效率。根據(jù)不同的用戶需要,也可以改變加載策略。
Hibernate緩存有一級緩存和二級緩存,對于一級緩存,其生命周期跟Session的生命周期一樣,所以也可以將Hibernate一級緩存稱為Session緩存。Hibernate一級緩存是一個(gè)強(qiáng)制的高速緩存。通過get()方法(load()方法也類似),我們可以得到一級緩存數(shù)據(jù),再次查詢就不需要get()方法了,直接查詢數(shù)據(jù)對象就行。需要注意的是get()方法是通過id來加載的,而list()方法也會將查詢結(jié)果放置在一級緩存中,但是它不會去一級緩存中查找獲取數(shù)據(jù),原因是list()方法不是通過id加載的,還有iterate方法,例如: Iterator<Seeker> iter = session.createQuery(“from **").iterate(); 該語句只把ID的值放到迭代器中,當(dāng)遍歷的時(shí)候,會根據(jù)ID的值再去數(shù)據(jù)庫中查。并且該語句會產(chǎn)生N+1次查詢。
至于二級緩存是由SessionFactory負(fù)責(zé)管理,所以也常將二級緩存稱為SessionFactory緩存。主要適用于不太重要的數(shù)據(jù),所以也沒深入的了解。
一周的Hibernate課程學(xué)習(xí)就到此為止了,Hibernate的相關(guān)知識還很多,以后要多在實(shí)戰(zhàn)項(xiàng)目中運(yùn)用才能更好地體會。
相關(guān)文章
java中MultipartFile互轉(zhuǎn)File的方法
本文主要介紹了java中MultipartFile互轉(zhuǎn)File的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
Java分布式學(xué)習(xí)之Kafka消息隊(duì)列
Kafka是由Apache軟件基金會開發(fā)的一個(gè)開源流處理平臺,由Scala和Java編寫。Kafka是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng),它可以處理消費(fèi)者在網(wǎng)站中的所有動作流數(shù)據(jù)2022-07-07
如何讓java只根據(jù)數(shù)據(jù)庫表名自動生成實(shí)體類
今天給大家?guī)淼闹R是關(guān)于Java的,文章圍繞著如何讓java只根據(jù)數(shù)據(jù)庫表名自動生成實(shí)體類展開,文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
Mybatis-Plus使用MetaObjectHandler實(shí)現(xiàn)自動填充實(shí)體對象字段
在我們使用Mybatis-Plus時(shí),一些簡單的CRUD,你會發(fā)現(xiàn)好多表,許多字段是重復(fù)的,如果我們每次更新或者新增,都要手動賦值,那么會出現(xiàn)許多不必要的重復(fù)操作,所以本文介紹了Mybatis-Plus使用MetaObjectHandler實(shí)現(xiàn)自動填充實(shí)體對象字段,需要的朋友可以參考下2024-11-11
Java中Stream的flatMap與map使用場景及區(qū)別詳解
這篇文章主要介紹了Java中Stream的flatMap與map使用場景及區(qū)別詳解,Stream 流式操作,一般用于操作集合即 List 一類的數(shù)據(jù)結(jié)構(gòu),簡單來說 Stream 的 map 使得其中的元素轉(zhuǎn)為另一種元素的映射(map)方法,需要的朋友可以參考下2024-01-01
解決IDEA springboot"spring-boot-maven-plugin"報(bào)紅問題
這篇文章主要介紹了解決IDEA springboot"spring-boot-maven-plugin"報(bào)紅問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
MyBatis中的表關(guān)聯(lián)查詢實(shí)現(xiàn)示例
這篇文章主要介紹了MyBatis中的表關(guān)聯(lián)查詢實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
IntelliJ IDEA創(chuàng)建maven web項(xiàng)目的圖文步驟(IDEA新手適用)
這篇文章主要介紹了IntelliJ IDEA創(chuàng)建maven web項(xiàng)目的圖文步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03

