Hibernate4實戰 之第六部分:基本實現原理

整體流程
1:通過configuration來讀cfg.xml文件
2:得到SessionFactory 工廠
3:通過SessionFactory 工廠來創建Session實例
4:通過Session打開事務
5:通過session的api操作數據庫
6:事務提交
7:關閉連接
說明:以下分方法描述的實現流程並不是Hibernate的完整實現流程,也不是Hibernate的完整實現順序,只是描述了Hibernate實現這些方法的主幹和基本方式,主要是用來理解這些方法背後都發生了些什麼,如果需要詳細完整的實現流程,請查閱Hibernate相應文檔和源代碼
當我們調用了session.save(UserModel)後:
1:TO--->PO: Hibernate先在緩存中查找,如果發現在內部緩存中已經存在相同id的PO,就認爲這個數據已經保存了,拋出例外。
如果緩存中沒有,Hibernate會把傳入的這個TO對象放到session控制的實例池去,也就是把一個瞬時對象變成了一個持久化對象。
如果需要Hibernate生成主鍵值,Hibernate就會去生成id並設置到PO上
2:客戶端提交事務或者刷新內存
3:根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
4:根據hbm.xml文件和model來動態的拼sql,如下:
insert into 表名(來自hbm.xml) (字段名列表(來自hbm.xml )) values(對應的值的列表(根據hbm.xml從傳入的model中獲取值))
5:真正用JDBC執行sql,把值添加到數據庫
6:返回這個PO的id。
當我們調用了session.update(UserModel)後:
1:DO--->PO:首先根據model 的主鍵在hibernate的實例池中查找該對象,找到就拋出錯誤。
如果沒有就DO--->PO,Hibernate會把傳入的這個DO對象放到session控制的實例池去,也就是把一個瞬時對象變成了一個持久化對象
2:客戶端提交事務或者刷新內存
3:根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
4:根據hbm.xml文件和model來動態的拼sql,不進行髒數據檢查,如下:
update 表名(來自hbm.xml) set 字段名(來自hbm.xml )=值(根據hbm.xml從傳入的model中獲取值) where 條件
5:真正用JDBC執行sql,把值修改到數據庫
當我們調用了session.update(UserModel)後:

1:首先根據model 的主鍵在hibernate的實例池中查找該對象,找到就使用該PO對象(用來檢查髒數據)。
2:客戶端提交事務或者刷新內存
3:Hibernate會進行髒數據檢查,如果沒有數據被修改,就不執行下面的步驟了。
4:根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
5:根據hbm.xml文件和model來動態的拼sql,進行髒數據檢查(如果開啓了dynamic-update的話),如下:
update 表名(來自hbm.xml) set 字段名(來自hbm.xml )=值(根據hbm.xml從傳入的model中獲取值) where 條件
6:真正用JDBC執行sql,把值修改到數據庫
Id的生成方式爲assigned的情況
當我們調用了session.delete(UserModel)後:
1:根據model的主鍵在數據庫裏面查找數據,來保證對象的存在,然後把找到的對象放到內存裏面,如果此時在hibernate的實例池中已經存在對應的實體對象(注意:代理對象不算實體對象),就拋出例外。
2:如果此時在hibernate的實例池中不存在對應的實體對象,那麼就把對象放到內存裏面,但會標識成待刪除的對象,就不可以被load等使用了。
3:如果對象還是不存在,那麼就直接返回了(注意,這個時候是不拋出例外的)。也就是說,delete之前會執行一個查詢語句。
4:客戶端提交事務或者刷新內存
5:判斷待刪除的PO是否存在,存在才需要刪除,否則不需要刪除
6:如果要刪除,才執行以下的步驟。先根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
7:根據hbm.xml文件和model來動態的拼sql,如下:
delete from 表名(來自hbm.xml) where 主鍵=值(來自model)
8:真正用JDBC執行sql,把數據從數據庫中刪除
Id的生成方式爲非assigned的情況
n當我們調用了session.delete(UserModel)後:
1:根據model的主鍵在hibernate的實例池中查找對應的實體對象(注意:代理對象不算實體對象),找到就拋出例外。
2:如果內存中沒有對應的實體對象,就什麼都不做。
3:客戶端提交事務或者刷新內存
4:先根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
5:根據hbm.xml文件和model來動態的拼sql,如下:
delete from 表名(來自hbm.xml) where 主鍵=值(來自model)
6:真正用JDBC執行sql,把數據從數據庫中刪除,如果數據不存在,就拋出例外
當我們調用了session.delete(UserModel)後:
1:根據model的主鍵在hibernate的實例池中查找對應的實體對象(注意:代理對象不算實體對象),找到就使用該對象。
2:如果內存中沒有對應的實體對象,就到數據庫中查找來保證對象的存在,把找到的對象放到內存裏面,而且不會標識成待刪除的對象,可以繼續被load等使用。代理對象也需要去數據庫中查找數據。
3:如果對象還是不存在,那麼就拋出例外。也就是說,delete之前可能會執行一個查詢語句。
4:客戶端提交事務或者刷新內存
5:根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
6:根據hbm.xml文件和model來動態的拼sql,如下:
delete from 表名(來自hbm.xml) where 主鍵=值(來自model)
7:真正用JDBC執行sql,把數據從數據庫中刪除
當我們調用了s.load(UserModel.class, “主鍵值");後:
1:根據model類型和主鍵值在一級緩存中查找對象,找到就返回該對象
2:如果沒有找到,判斷是否lazy=true,如果是,那就生成一個代理對象並返回;否則就先查找二級緩存,二級緩存沒有,就查找數據庫。如果是返回代理對象的,在第一次訪問非主鍵屬性的時候,先查找二級緩存,二級緩存中沒有才真正查找數據庫。
3:如果需要查找數據庫的話,會根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
4:根據hbm.xml文件和model來動態的拼sql,如下:
select 字段列表(來自hbm.xml) from 表名(來自hbm.xml) where 主鍵=值
5:真正用JDBC執行sql,把數據從數據庫中查詢出來到rs裏面。如果找不到就報錯
6:從結果集---〉Model,然後返回model
注意:load方法開不開事務都可以執行查詢語句。

當我們調用了s.get(UserModel.class, “主鍵值");後:
1:先根據model類型和主鍵值查找緩存,如果存在具體的實體對象,就返回;如果存在實體的代理對象(比如前面load這條數據,但是還沒有使用,那麼load生成的是一個只有主鍵值的代理對象),那麼查找數據庫,把具體的數據填充到這個代理對象裏面,然後返回這個代理對象,當然這個代理對象此時已經完全裝載好數據了,跟實體對象沒有什麼區別了。
2:如果要查找數據庫,先根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
3:根據hbm.xml文件和model來動態的拼sql,如下:
select 字段列表(來自hbm.xml) from 表名(來自hbm.xml) where 主鍵=值
4:真正用JDBC執行sql,把數據從數據庫中查詢出來到rs裏面,沒有值就返回null
5:從結果集---〉Model,然後返回model
注意:get方法開不開事務都可以執行查詢語句。
當我們調用了q.list();後:
1:對HQL進行語義分析,分析出model來
2:根據model類型和cfg.xml中映射文件的註冊來找到相應的hbm.xml文件
3:根據hbm.xml文件和model,來解析HQL,從而實現動態的把HQL轉換成對應的sql,(從hql---〉sql這個過程是非常複雜的,不但區分不同的數據庫,還包括了對sql進行自動的優化),這裏只能簡單的示例如下:
select 字段列表(來自hbm.xml) from 表名(來自hbm.xml) where 條件
4:真正用JDBC執行sql,把數據從數據庫中查詢出來到rs裏面
5:從結果集---〉Model集合(或對象數組),然後返回model集合(或對象數組)
注意:list()方法開不開事務都可以執行查詢語句。
視頻配套PPT,視頻地址【 Hibernate4實戰-獨家視頻課程
發佈了27 篇原創文章 · 獲贊 4 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章