mybatis association 懶載入實現原理
阿新 • • 發佈:2019-01-29
前言
mybatis的association
標籤可以設定關聯物件,載入方式;如下的user關聯dept,載入方式fetchType=”eager”
<resultMap id="BaseResultMap" type="testmaven.entity.User">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="dept_id" jdbcType="INTEGER" property="deptId" />
<association property ="dept" column="dept_id" fetchType="eager" select="testmaven.mapper.DeptMapper.selectByPrimaryKey" ></association>
</resultMap>
以上的配置、意義咱們都知道。但是這裡有兩個問題,第一,主資料以什麼方式獲取的關聯物件,是兩個表關聯查詢的還是獲取主資料後一條一條的查詢的從資料,如果是這樣那麼就會存在N+1的問題?再就是,懶載入時,只有用到主資料時,才會查詢關聯資料,那麼這個“用到”是什麼意思?
關聯資料獲取的原理
association資料的獲取,都是先獲取主資料,然後根據主資料的某些欄位獲取關聯資料,是一條條查詢的,並不是多表關聯查詢的,這種方式存在查詢N+1問題
eager
query主資料時,會立刻query關聯資料,這兩個query使用的同一個jdbc connection。
lazy
query主資料庫時,不會query關聯資料,只有在呼叫主資料的方法時,才會query獲取資料(比如例中user.toString()、user.getName()等方法),這兩個query使用不同connection
到這裡,第一個問題,解決了,繼續往下看。
懶載入的實現原理
經過debug發現,在執行主資料的方法時(user.toString()、user.getName()),才會獲取資料。mybatis怎麼實現的?原來mapper返回的類是代理類,mybatis使用javassist技術建立代理類,然後代理類任何方法都會呼叫JavassistProxyFactory$EnhancedResultObjectProxyImpl
圖1
圖2
圖3
更深層次的研究,打算將代理類輸出到磁碟,反編譯檢視它的原始碼,這部分在研究javassist後再來補充。