Hibernate 簡介
1. 前言
大家好!本節(jié)課將和大家一起學習鼎鼎有名的 Hibernate 框架。
本節(jié)課程將向大家介紹:
- Hibernate 的功能 、特點;
- Hibernate 產(chǎn)生的背景;
- 并初步探討編寫 Jdbc 框架的基礎構建思路。
2. Hibernate 是什么

簡而言之:
- Hibernate 是一個 Java Jdbc 框架,用來簡化 Java Jdbc 操作;
- Hibernate 也是一個ORM 框架,可以自動完成關系數(shù)據(jù)庫中關系型數(shù)據(jù)到 Java 對象型數(shù)據(jù)的映射;
- 當然,還可以說是一個持久化框架。
以上說法其實是對完成同一件事情不同角度的詮釋。
Hibernate 的出現(xiàn)就是想讓開發(fā)者的編碼工作變得簡單,這個簡單指不需要在非核心邏輯編寫上花費太多時間。
3. Hibernate 的發(fā)展歷史
喝水不忘挖井人,先了解下 Hibernate 的發(fā)展歷程。
故事的大致情節(jié)就是澳大利亞墨爾本一位名為 Gavin King 的 27 歲的程序員嫌棄原有的 Jdbc 編碼工作方式太過無聊、無腦。于是就買了一本 SQL 編程的書籍在不長的時間內(nèi)寫了這么一個叫 Hibernate 的框架。
Hibernate 一出江湖,便一鳴驚人如此而已;
Hibernate 承載了一個程序員的勵志故事。
Hibernate 由最初的 1.0 版本演變到了現(xiàn)在 6.x 版本(官網(wǎng)最新顯示),功能越來越強大,體積當然也越來越強大。
至于你愛不愛它,還是要看項目的需要。
故事講完,繼續(xù)!
4. Hibernate 的特點
和 Hibernate 類似的框架很多,比如 Mybatis 之類。但是 Hibernate 在江湖上的地位一直都比較穩(wěn)定,追捧之人眾多。當然,各喜所愛!在每一個程序員的心里都會有自己的白馬王子。
Hibernate 特點如下:
- 完全面向?qū)ο蟛僮鳎?/strong> 操作過程可以忘記 Jdbc API 帶來的傷痛;
- 操作簡單: 復雜的查詢也只需幾行代碼,可以全身心去做核心業(yè)務邏輯;
- 沒有反射就沒有框架: 操作簡單的代價是底層封裝代碼的負重前行,Hibernate 適合業(yè)務邏輯復雜的場景,不適合數(shù)據(jù)量很大的應用;
- Hibetnate 提供了專業(yè)級生產(chǎn)環(huán)境中的事務、緩存、并發(fā)等多種容錯、高性能、高穩(wěn)定性的解決方案。產(chǎn)品上線后,可減少開發(fā)者的后顧之憂,不用擔心什么時候會有只 Bug 突然爬出來;
- 簡單易學,操作方便,學習成本較低。還有……還有……就是 Hiberate 提供一種框架設計思想,其開發(fā)理念對開發(fā)者可產(chǎn)生思想層面影響。
5. Hibernate 與其它框架的比較
-
更適合現(xiàn)代開發(fā)理念: 產(chǎn)品的生命周期決定產(chǎn)品的市場價值,快速迭代開發(fā)是主流。Hibernate 能讓開發(fā)者高度關注項目的核心業(yè)務邏輯,而不因重復繁雜的數(shù)據(jù)庫連接操作影響產(chǎn)品的迭代周期;
-
說到 Hibetnate,就會談到與之齊名的 MyBatis,MyBatis 以半開發(fā)模式吸引開發(fā)者,讓開發(fā)者在開發(fā)過程具有一定的把控感。但是,在數(shù)據(jù)庫操作大的情況下書寫SQL語句并不是一件輕松之事;對業(yè)務量多、數(shù)據(jù)庫操作相對較少的情況,書寫些常規(guī)性SQL想必也帶來不了成就感。不如 Hibernate 來的簡單直接;
-
Hibernate 提供多元化的操作模式。純粹主義者能以完全面向?qū)ο蠓绞讲僮鳎?strong>Hibernate 也提供了原生SQL操作模式,適合對原生 SQL 語句鐘情者;對于復雜的數(shù)據(jù)操作,也支持存儲過程調(diào)用。應有盡有,總能找到自己喜歡的感覺。
專業(yè)的角度,無論哪一種 Jdbc 框架,其要解決的問題都是一樣的,其核心原則和思想是一樣的。Hibetnate 是一個封裝的嚴絲合縫的開源框架,其內(nèi)在的代碼架構和代碼實現(xiàn)模式對于學習者無疑是一座寶藏。這點其它框架就無法與其一比。
6. Jdbc 框架形成過程
6.1 什么是持久化
要真正了解、認識 Hibernate, 先切換一下鏡頭,回到?jīng)]有Hibernate 之前的世界,一起來了解框架的演變過程(有需求才會有市場嘛)。
現(xiàn)在是提問時間:
程序的本質(zhì)是什么?
-----------------------我是等待你答案的中劃線-----------------------
程序的本質(zhì)是解決現(xiàn)實中的問題,解決問題之前,先解決第一個問題,用計算機建模并保存現(xiàn)實生活中的信息,這個過程叫信息數(shù)據(jù)化。
然后,按需求對數(shù)據(jù)進行邏輯處理并產(chǎn)生結果數(shù)據(jù)。程序是從數(shù)據(jù)到數(shù)據(jù)的過程,當然,算法功底很重要。
程序運行時的數(shù)據(jù)是保存在內(nèi)存中的,叫臨時數(shù)據(jù)或叫瞬時數(shù)據(jù)。
程序運行過程產(chǎn)生的數(shù)據(jù)有些是需要永久性保存的,選擇介質(zhì)較多,一般會選擇保存在數(shù)據(jù)庫中,Java 程序員可以使用 Jdbc Api 和數(shù)據(jù)庫進行交互。
把程序中的數(shù)據(jù)寫回數(shù)據(jù)庫這個過程也可稱為數(shù)據(jù)持久化過程。
6.2 Java Jdbc 框架演變之路
先回顧一下純手工 Jdbc 操作流程:
- 加載由不同廠商遵循 Jdbc 規(guī)范開發(fā)的驅(qū)動類。關于 Jdbc 驅(qū)動類開發(fā)不是這里要講的,可查閱相關資料;
Class.forName("對應數(shù)據(jù)庫的驅(qū)動類名");
- 建立 Java 程序和數(shù)據(jù)庫系統(tǒng)的連接。本質(zhì)是進程和進程的網(wǎng)絡連接;
Connection conn = DriverManager.getConnection("url","用戶名","密碼");
- 確定數(shù)據(jù)清單。數(shù)據(jù)庫只認 SQL 語句,你需要數(shù)據(jù)庫幫你做什么樣的數(shù)據(jù)操作,需要傳送 SQL 指令給數(shù)據(jù)庫;
String sql="使用sql語法描述數(shù)據(jù)需求";
- 需要一個信使。創(chuàng)建一個語句處理對象充當信使,任務就是上傳下達;
PreparedStatement preparedStatement=conn.prepareStatement(sql);
- 信使工作,把程序中的數(shù)據(jù)搬運到數(shù)據(jù)庫,或把數(shù)據(jù)庫數(shù)據(jù)搬運到程序;
preparedStatement.各種方法();
- 數(shù)據(jù)搬運過來后,Java 代碼要用呀!Java 語言有什么特點?面向?qū)ο髥??搬運過來的數(shù)據(jù)是符合關系數(shù)據(jù)庫特點的數(shù)據(jù),于是開始手工數(shù)據(jù)格式轉(zhuǎn)換、封裝;
省略若干代碼,心里希望表結構中字段不要太多!此時的苦只有自己知道?。?br> 7. 最后把封裝成 OOP 的數(shù)據(jù)交付給 Java 業(yè)務代碼使用,各種資源關閉。
在編碼時,只要涉及到和數(shù)據(jù)交互行為。好吧,把前面的幾個步驟再走一遍。發(fā)現(xiàn)沒有,其實你在做大量的重復工作,好好的腦力活生生變成了體力活。
怎么辦?難道要承受這種編程生活的折磨嗎,當然不!
通過模板方法解決 Jdbc 訪問中的重復性問題。
其實,Jdbc 編程是一個模板化的操作過程,針對不同的數(shù)據(jù)請求操作其中只有 2 個地方是不一樣的。
- 數(shù)據(jù)清單不一樣。每一次、不同數(shù)據(jù)需求的 Jdbc 操作請求,SQL 語句是不一樣的。
- 另一個不一樣是從關系數(shù)據(jù)庫中讀出來的數(shù)據(jù)封裝成對應的目標對象類型是不一樣的。
知道這些就好辦,可以把 Jdbc 代碼操作封裝成一個模板方法。在模板方法中預留 2 個參數(shù):
- 傳入 SQL 語句;
- 傳入一個用于封裝結果集中的數(shù)據(jù)到 OOP 對象的方法。
按照這個思路,屬于你的 Jdbc 簡易框架就要誕生了。有點激動吧!
如下是查詢模板方法代碼參考:
/**
*通用 jdbc 查詢數(shù)據(jù)模板方法
*connection:連接對象,可由外部傳入,也可由內(nèi)部方法創(chuàng)建
*sql:傳過來的 SQL語句
*rsh:自定義結果集處理接口,其中有封裝結果集數(shù)據(jù)的方法
*args:SQL中參數(shù)值
*/
public <T> T query(Connection connection, String sql, ResultSetHandler<T> rsh, Object... args) throws SQLException {
// 建立連接
if (connection == null)
connection = this.dataSource.getConnection();
if (sql == null)
throw new SQLException("SQL語句不正確");
// 預處理語句
PreparedStatement preStatement = connection.prepareStatement(sql);
// SQL指定參數(shù)值
fillStatement(preStatement, args);
// 結果集
ResultSet rs = preStatement.executeQuery();
// 結果處理規(guī)范
T result = rsh.handle(rs);
// 資源關閉
this.close(connection, preStatement, rs);
return result;
}
調(diào)用上面方法時,傳遞一條 SQL 語句,傳遞一個實現(xiàn)了 ResultSetHandler 接口的對象(此對象提供方法完成數(shù)據(jù)映射工作)就可以了。
我們編寫的模板方法與 Hibernate 相比較:
- Hibernate 會自動構建生成 SQL 語句。復雜的 SQL 也不是問題;
- 自動完成了關系型數(shù)據(jù)庫中的數(shù)據(jù)到 Java 對象的封裝。
所以說Hibernate 是一個全自動化的 ORM 持久化框架。
當然 Hibernate 可不僅只完成數(shù)據(jù)庫數(shù)據(jù)的訪問,還會考慮性能、事務等生產(chǎn)環(huán)境中的諸多現(xiàn)實問題,這些會在本課程后面慢慢展開。
7. 學習基礎
學習 Hibernate 分 2 個層次:
- 把 Hibernate 當成一個工具, 掌握其應用。只需要學習者具有一定的 JAVA 基礎知識即可;
- 了解 Hibernate 底層運行機制,對其運行過程進行調(diào)優(yōu),則需要學習者具有反射、網(wǎng)絡編程、多線程等相關知識的儲備。
8. 小結
好了!到了總結時間:
本章節(jié)幫助大家初步了解 Hibernate 框架的作用。和原生態(tài)Jdbc 操作相比較,可發(fā)現(xiàn) Hibernate 解決了 Jdbc 操作中的 SQL 語句生成問題、關系數(shù)據(jù)庫中數(shù)據(jù)自動映射問題。
Hibernate通過提供統(tǒng)一的接口方式讓用戶以面向?qū)ο蟮姆绞酵该鞯?、簡單地使用Jdbc連接數(shù)據(jù)庫。
讓開發(fā)者從繁瑣無太多技術含量的編碼中解脫出來,用更多的心思和時間完成核心業(yè)務邏輯。