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()方法開不開事務均可以執行查詢語句。
 原創內容 轉自請註明【  http://sishuok.com/forum/blogPost/list/2483.html#7182
視頻配套PPT,視頻地址【  Hibernate4實戰-獨家視頻課程 】
相關文章
相關標籤/搜索