您好,登錄后才能下訂單哦!
整體流程
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的情況
當我們調用了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()方法開不開事務都可以執行查詢語句。
總結
以上所述是小編給大家介紹的hibernate4基本實現原理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。