Mybatis 延遲加載的實現原理詳細解析
(1)代理對象機制的深入探討
代理對象的生成:Mybatis 使用代理對象來實現延遲加載是基于 Java 的代理機制。當開啟延遲加載并且配置正確后,對于需要延遲加載的關聯對象,Mybatis 會創建一個代理對象。這個代理對象是在運行時動態生成的,它的生成過程涉及到 Java 的反射機制。以 Java 動態代理為例,Mybatis 會實現一個InvocationHandler接口,在這個接口的invoke方法中,會處理對代理對象方法的調用。
方法攔截原理:當外部代碼調用代理對象的方法時,實際上是調用了InvocationHandler接口的invoke方法。在invoke方法中,代理對象會首先檢查關聯對象是否已經被加載。這個檢查過程是通過判斷一個標志位或者查看緩存來實現的。如果關聯對象還沒有被加載,代理對象就會觸發加載過程。例如,假設代理對象是一個List類型的關聯對象的代理(如前面提到的商品圖片集合),當調用list.size()方法時,invoke方法會檢測到如果關聯對象(真實的商品圖片列表)還沒有被加載,就會執行加載操作。
代理對象與真實對象的替換:在關聯對象加載完成后,代理對象會將自己替換為真實的對象。這個替換過程需要考慮到對象的類型兼容性和引用一致性。例如,在 Java 中,如果代理對象是ArrayList的代理,加載完成后的真實對象也是ArrayList,那么代理對象會將自己在內存中的引用替換為真實的ArrayList對象的引用。這樣,在后續的方法調用中,就可以直接使用真實對象,而不會再經過代理對象的攔截。
(2)加載過程的詳細步驟
查詢語句的構建與執行:當代理對象檢測到需要加載關聯對象時,它會根據在映射文件中配置的信息構建查詢語句。這個過程涉及到解析select屬性指定的查詢方法以及column屬性指定的參數。以之前的商品和商品圖片的例子來說,代理對象會從ProductImageMapper.getProductImagesByProductId這個方法簽名和product_id這個參數構建出一個完整的 SQL 查詢語句,然后通過 Mybatis 的SqlSession對象執行這個查詢語句。在執行查詢語句時,Mybatis 會使用配置好的數據源、數據庫驅動等組件,將 SQL 語句發送到數據庫服務器進行查詢。
數據的映射與填充:數據庫返回查詢結果后,Mybatis 會根據結果集和實體類的映射關系(通常在resultMap中定義)將數據填充到關聯對象中。這個映射過程類似于普通的查詢結果映射,但在延遲加載場景下,需要將數據填充到之前未加載的關聯對象中。例如,對于商品圖片的查詢結果,Mybatis 會根據ProductImage實體類的屬性和結果集的列名、列值的對應關系,將數據逐一填充到ProductImage對象中,然后將這些對象添加到關聯對象(如productImages集合)中。
加載過程中的異常處理:在加載過程中,可能會出現各種異常情況,如數據庫連接失敗、SQL 語法錯誤、查詢結果為空等。Mybatis 會對這些異常進行處理。如果是數據庫連接失敗等嚴重錯誤,會將異常向上拋出,可能導致整個操作失敗。如果是查詢結果為空,會根據具體的配置和業務需求進行處理,可能是返回一個空的關聯對象(如空集合),也可能是拋出一個輕微的警告信息。
(3)緩存機制在延遲加載中的作用
一級緩存的影響:Mybatis 的一級緩存是基于SqlSession的緩存。在延遲加載場景下,當一個SqlSession內首次加載關聯對象后,數據可能會被緩存到一級緩存中。如果在同一個SqlSession內再次訪問相同的關聯對象,就可以直接從緩存中獲取數據,而不需要再次執行查詢語句。例如,在一個事務處理過程中,第一次加載了商品的圖片關聯對象,之后在同一事務(同一個SqlSession)中再次訪問商品圖片時,就可以利用一級緩存提高性能。
二級緩存的作用(如果啟用):二級緩存是基于Mapper的緩存,范圍比一級緩存更廣。如果在配置中啟用了二級緩存,并且關聯對象的查詢符合二級緩存的規則,那么在不同的SqlSession之間也可以共享緩存數據。這對于頻繁訪問的關聯對象來說,可以大大減少數據庫查詢次數。不過,在使用二級緩存時,需要注意緩存的一致性問題,因為不同的SqlSession可能會對數據進行修改,導致緩存數據與數據庫中的實際數據不一致。在延遲加載場景下,二級緩存的更新策略和緩存清除機制需要謹慎設計,以確保緩存數據的準確性和及時性。
————————————————
? ? ? ? ? ? ? ? ? ? ? ? ? ? 版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
? ? ? ? ? ? ? ? ? ? ? ??
原文鏈接:https://blog.csdn.net/aaaa_1111111/article/details/144152482