1. 程式人生 > >mybatis面向介面程式設計實踐與mapper代理物件的產生

mybatis面向介面程式設計實踐與mapper代理物件的產生

上篇提到面向介面程式設計需要使用getMapper獲取代理物件,今天我們來看一下mapper代理物件是如何產生的,在此之前先回憶下面試介面程式設計。 一、Mybatis面向介面程式設計實踐 (一)使用xml的方式 1.定義mapper介面 Mapper介面就是一個普通的介面。 在這裡插入圖片描述 2.定義mapper對映檔案 在這裡插入圖片描述 3.在全域性配置檔案中配置mapper對映檔案 上篇我們也說過,雖有多種方式觸發檔案解析與介面注入,不做此步驟也能完成(搞清楚一個前提我們現在說的都是在mybatis面向介面程式設計方式下),但是我們建議通過配置對映檔案的方式觸發mybatis自動掃描注入。配置方式有多種,不在贅述。我們的配置方式如下: 在這裡插入圖片描述

4.現在我們測試一下 在這裡插入圖片描述 測試結果ok。 (二)使用註解的方式。 1.定義mapper介面,同時使用註解 在這裡插入圖片描述 2.介面注入。 上篇我們也提到過,雖然用註解不需要xml對映檔案,但我們可以通過配置一個只含有namespace的對映檔案觸發介面注入。如下: 在這裡插入圖片描述 假如我們就是不配置,可以在使用之前呼叫 sqlsession.getConfiguration().addMapper(IUser.class); 3.測試,假設沒有配置xml 在這裡插入圖片描述 測試ok. 二、Mybatis面向介面程式設計之mapper物件的產生

在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述 mapperRegistry中getMapper,首先通過Class型別在knowMappers中獲取mapperProxyFactory.這個變數就是個hashMap,是所有註冊的mapper介面,上篇我們提到過。方法直接返mapperProxyFactory.newInstance(sqlSession).我們接著看下 在這裡插入圖片描述

由此可以看出mybatis直接使用了jdk的動態代理產生了一個mapper介面代理物件。 MapperProxy就是是個InvocationHandler我 們看一下MapperProxy的invoke方法, 在這裡插入圖片描述 如果是object中的方法直接呼叫,比如hashCode,wait.toString…這些,我們介面中並沒有default方法。最終會呼叫最後兩行。 接著看下MapperMethod物件的產生

在這裡插入圖片描述 他有一個快取避免了每次都重新生成一個物件,因為這個物件的建立過程比較複雜。 構造方法如下: 在這裡插入圖片描述 SqlCommand和MethodSignature為兩個內部類,先看一下SqlCommand

在這裡插入圖片描述

裡面如下方法是去全域性配置物件查詢解析的sql語句生成的類物件,id為介面全類名+方法名,for迴圈為遞迴呼叫,因為介面存在繼承關係,方法不一定都宣告在本類,也可能在父類,父類的父類。。。。。。。。 在這裡插入圖片描述 Come on 在這裡插入圖片描述 通過剛才的satementId取判斷Configuration中成員物件mappedStatement中是否包含 在這裡插入圖片描述 這個物件便是所有解析的sql語句生成的類物件的map集合,為內部類,繼承了hashMap,,重寫了put,get方法。key即為namespace+語句id和語句id,兩個key對應相同物件,這也是什麼用mybatis的時候,語句可以不寫namespace的原因。具體解析以後再分析。

判斷如果存在對應的sql語句,則取到相應的MappedStatement物件,這個物件包含了對映檔案中定義的語句(如select)的所有資訊,比如引數,返回值,具體sql,型別(增刪蓋查)。。。等等等 內部類MethodSignature定義了介面中方法的各種資訊。

在這裡插入圖片描述 至此MapperMethod物件完成建立。接下來呼叫execute方法。

在這裡插入圖片描述 該方法中根據語句型別,迴歸原始直接呼叫了sqlSession中的增刪蓋查方法,執行sql.根據配置和方法資訊拼裝返回結果。到此一個實現了mapper介面的代理物件生成完成,所以你可以盡情的使用此物件呼叫方法啦。