對於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的相關知識還很多,以後要多在實戰項目中運用才能更好地體會。