Hibernate是一個優秀的Java 持久化層解決方案,是當今主流的對象—關係映射(ORM)工具
對於Hibernate剛剛學習了一周時間了,作為一名java初學者,也有點自己的感受想分享出來,如果這篇文章能有幸被大家看到,也僅供大家娛樂。如果有什麼不足之處,歡迎大家多多指點,多多批評。僅供參考,不喜勿噴。
前段時間剛學習了用JDBC來進行java和資料庫的串連,來實現對資料的持久化操作和增刪改查,但是學習完的感受就是JDBC過於繁瑣,因為它無 法直接面對對象,開發效率地,代碼又多,還重複,完全不符合java物件導向的思維模式。Hibernate的誕生算是給java程式員很好地解決了這個 問題,所以我們可以忘掉JDBC了,來看看Hibernate是如何?java的持久化操作的。
Hibernate是一個優秀的Java 持久化層解決方案,是當今主流的對象—關係映射(ORM)工具。它的優勢有三點,第一:它是一個開發原始碼的對象關係映射架構;第二:對JDBC進行了非 常輕量級的對象封裝, 簡化了JDBC 繁瑣的編碼;第三:將JavaBean對象和資料庫的表建立對應關係。ORM是持久化層的一種解決方案,它是將java中的類對象及相關屬性和相關類與數 據庫中的表及表的屬性和鍵做相關的一一映射,來實現java對象和資料庫的聯絡。下面我就來具體說說自己是如何學習Hibernate的。
一:hibernate入門
對 於搭建項目架構編寫hibernate設定檔、實體對應檔我就不多說了。首先我們要先用Configuration介面來建立會話工廠,再從 SessionFactory(會話工廠)裡獲得會話執行個體(一般情況下,整個應用只有唯一的一個SessionFactory,它應該在應用初始化時被創 建),然後擷取Session執行個體,用Session可以操作資料庫和類中的對象,用Transaction介面的commit()和 roolback()方法來提交事務和復原事物,用Query來對資料庫實現查詢(用SQL或HQL)。另外在對資料進行增刪改查操作 時,Hibernate中的實體物件有三種對象:瞬時狀態,持久狀態,游離狀態。狀態不同,實現方法也不相同。大家可以自己慢慢體會。
二:關聯映射
既然 Hibernate是關係映射工具,必然存在many-to-one,one-to-many,雙向一對多,many-to-many關聯。要實現這些操 作,首先實體之間要有關聯關係,即通過一個對象持有另一個對象的執行個體。而在資料庫的表中,表的主外鍵也能實現表與表的關聯關係。然後我們就要把這些關聯關 系在對應檔(hbm.xml)中體現出來。many-to-one是many的一端應持有one的一端的對象(引用),one-to-many是one 的一端應持有many端的對象集合,雙向一對多就是同時配置了單向的一對多和單向的多對一,多對多關聯則是將多對多轉換成兩個一對多,而且為中間表建立實 體類及對應檔,兩個端點和中間端分別建立雙向一對多關聯。
三:HQL實用技術
Hibernate 支援兩種主要的查詢方式。HQL(Hibernate Query Languge,Hibernate 查詢語言)查詢是一種物件導向的查詢語言,其中沒有表和欄位的概念,只有類、對象和屬性的概念,HQL 是應用較為廣泛的方式。Criteria 查詢又稱為“物件查詢”,它用物件導向的方式將構造查詢的過程做了封裝。
HQL相比與SQL更符合java物件導向思維,也更加簡單。HQL中沒有表和欄位的概念,只有類、對象和屬性的概念。例如你要查詢名字中帶有 “Spring”的一本書,SQL:select * from books where book_name like ‘%Spring%' HQL :from Book b where b.name like 'Spring%' SQL中用到的是資料庫中的表名books和欄位book_name,而HQL中用到的是Book類名和Book的name屬性,而Book類和 books表又是映射關係,所以相當於實現了資料庫的操作。是不是更加形象呢?
Criteria 查詢用的比較少,從Session中擷取Criteria執行個體,設定限制方法(用到Restrictions常用的查詢條件)。相當於把HQL語句轉化成一個個方法來實現查詢。看自己喜好吧,反正我是覺得HQL更實用一些吧。
四:HQL中的消極式載入和Hibernate快取
HQL 和Criteria查詢過程中都會消極式載入,有人覺得這是Hibernate的一個缺陷,我覺得這更像是Hibernate的高明之處。在得到一個 Session執行個體後,用Book為例,你用Session的get()方法得到一本Book,Book是主對象,而Book又有一個Type關聯對象, 但是得到的Book對象不會載入Type關聯對象,只有在你需要用到Type關聯對象時才會強制載入Type關聯對象,具體來說就是關聯對象和關聯集合的 預設載入計劃是:消極式載入,即載入主對象時它們不會被立即載入,而是直到使用這些對象和集合時才發送SQL語句、擷取資料、初始化對象和集合,而主對象的 屬性預設是被立即載入的。當然這種方式也是可以強制改變的,在用Criteria查詢時,你可以在實體類的對應檔中來添加 lazy = “false” 來強制載入。不過不建議這種方式,因為會造成不必要的資源浪費,效率也極低。如果需要,我們可以在編寫代碼時強制載入效果會更好一些。
總之,這種消極式載入策略會簡化SQL語句,提高查詢效率。根據不同的使用者需要,也可以改變載入策略。
Hibernate緩衝有一級緩衝和二級緩衝,對於一級緩衝,其生命週期跟Session的生命週期一樣,所以也可以將Hibernate一級緩衝 稱為Session緩衝。Hibernate一級緩衝是一個強制的快取。通過get()方法(load()方法也類似),我們可以得到一級快取資料, 重新查詢就不需要get()方法了,直接查詢資料對象就行。需要注意的是get()方法是通過id來載入的,而list()方法也會將查詢結果放置在一級 緩衝中,但是它不會去一級緩衝中尋找擷取資料,原因是list()方法不是通過id載入的,還有iterate方法,例如: Iterator<Seeker> iter = session.createQuery(“from **").iterate(); 該語句只把ID的值放到迭代器中,當遍曆的時候,會根據ID的值再去資料庫中查。並且該語句會產生N+1次查詢。
至於二級緩衝是由SessionFactory負責管理,所以也常將二級緩衝稱為SessionFactory緩衝。主要適用於不太重要的資料,所以也沒深入的瞭解。
一周的Hibernate課程學習就到此為止了,Hibernate的相關知識還很多,以後要多在實戰項目中運用才能更好地體會。