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