日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
聊聊Mybatis系列之Mapper接口

 1.上期回顧

創(chuàng)新互聯(lián)建站作為成都網(wǎng)站建設(shè)公司,專注網(wǎng)站建設(shè)公司、網(wǎng)站設(shè)計,有關(guān)企業(yè)網(wǎng)站設(shè)計方案、改版、費用等問題,行業(yè)涉及水電改造等多個領(lǐng)域,已為上千家企業(yè)服務(wù),得到了客戶的尊重與認可。

首先,我們還是回顧一下上篇文件的類容。先看下這個測試類,大家還有印象嗎:

 
 
 
 
  1. public class MybatisTest { 
  2.     @Test 
  3.     public void testSelect() throws IOException { 
  4.         String resource = "mybatis-config.xml"; 
  5.         InputStream inputStream = Resources.getResourceAsStream(resource); 
  6.         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
  7.         SqlSession session = sqlSessionFactory.openSession(); 
  8.         try { 
  9.             FruitMapper mapper = session.getMapper(FruitMapper.class); 
  10.             Fruit fruit = mapper.findById(1L); 
  11.             System.out.println(fruit); 
  12.         } finally { 
  13.             session.close(); 
  14.         } 
  15.     } 

上篇源碼分析講了 mybatis 一級緩存的實現(xiàn)原理。這次,我們來了解下 mybatis 接口的創(chuàng)建。

2. mapper接口的創(chuàng)建流程

2.1 SqlSession的getMapper()

首先,我們來看下 FruitMapper mapper = session.getMapper(FruitMapper.class); 這段代碼,意思很簡單,根據(jù)傳入的class 獲取這個對象的實例。這個流程有點復(fù)雜,阿粉帶著大家來跟下源碼:

首先還是ctrl + 左鍵點擊 getMapper 方法,然后會進入到 SqlSession 的 getMapper() 方法。然后之前阿粉也帶著大家了解了, SqlSession 的默認實現(xiàn)類是 DefaultSqlSession ,所以我們直接看下 getMapper() 在 DefaultSqlSession 里面的實現(xiàn):

 
 
 
 
  1. @Override 
  2. public  T getMapper(Class type) { 
  3.     return configuration.getMapper(type, this); 

2.2 Configuration 的getMapper()

這里從 configuration 里面去獲取, configuration 是全局配置對象,也就是上下文。參數(shù) this 是當(dāng)前的SqlSession 對象,繼續(xù)跟進去看下:

 
 
 
 
  1. public  T getMapper(Class type, SqlSession sqlSession) { 
  2.     return mapperRegistry.getMapper(type, sqlSession); 

2.3 MapperRegistry 的getMapper()

mapperRegistry 對象是干什么的呢?繼續(xù)點進去:

 
 
 
 
  1. public  T getMapper(Class type, SqlSession sqlSession) { 
  2.     final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory) knownMappers.get(type); 
  3.     if (mapperProxyFactory == null) { 
  4.         throw new BindingException("Type " + type + " is not known to the MapperRegistry."); 
  5.     } 
  6.     try { 
  7.         return mapperProxyFactory.newInstance(sqlSession); 
  8.     } catch (Exception e) { 
  9.         throw new BindingException("Error getting mapper instance. Cause: " + e, e); 
  10.     } 

這里就不好看懂了,需要先看下了解下 MapperRegistry 這個類,我們一步一步來,跟著阿粉的思路走:

 
 
 
 
  1. public class MapperRegistry { 
  2.  
  3.   private final Configuration config; 
  4.   private final Map, MapperProxyFactory> knownMappers = new HashMap<>(); 
  5.  
  6.   public MapperRegistry(Configuration config) { 
  7.     this.config = config; 
  8.   } 
  9.     ... 

了解一個類,首先看下成員變量和構(gòu)造方法。這里 config 不用多說了吧,主要的是 knownMappers 這個成員變量。這就是個map 對象,只是這個 map 對象的 value值是個對象,所以又要去看下 MapperProxyFactory 這個對象,點進去:

 
 
 
 
  1. public class MapperProxyFactory { 
  2.   private final Class mapperInterface; 
  3.   private final Map methodCache = new ConcurrentHashMap<>(); 
  4.  
  5.   public MapperProxyFactory(Class mapperInterface) { 
  6.     this.mapperInterface = mapperInterface; 
  7.   } 
  8.     ... 

首先,單獨看下這個類名 MapperProxyFactory ,取名是很有學(xué)問的,好的名字讓你一下就知道是干啥的。所以一看 MapperProxyFactory ,首先就會聯(lián)想到工廠模式,工廠模式是干啥的?創(chuàng)建對象的,創(chuàng)建什么對象呢?創(chuàng)建 MapperProxy 對象的。MapperProxy 也是有玄機的,Proxy 的是什么?看到這個一般都是使用代理模式來創(chuàng)建代理對象的。所以就很清楚了, MapperProxyFactory 這個類就是個工廠,創(chuàng)建的是 mapper 的代理對象。

然后這個類里面存的是 mapper 的接口和接口里面的方法。

最后,我們回到 MapperRegistry 類里面的 getMapper() 方法。現(xiàn)在是不是要清楚一些,通過 mapper 接口去 map 里面獲取工廠類 MapperProxyFactory ,然后通過工廠類去創(chuàng)建我們的 mapper 代理對象。然后在看下 getMapper() 方法里面的 mapperProxyFactory.newInstance(sqlSession); 這段代碼,繼續(xù)點進去:

 
 
 
 
  1. public T newInstance(SqlSession sqlSession) { 
  2.     final MapperProxy mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache); 
  3.     return newInstance(mapperProxy); 

你看,阿粉猜測對不對,MapperProxy 對象是不是出來了。然后看 newInstance() 這個方法:

 
 
 
 
  1. protected T newInstance(MapperProxy mapperProxy) { 
  2.     return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); 
  3.   } 

兩個 newInstance() 方法都在MapperProxyFactory 這個類里面,這里就很明顯嘛。典型的 JDK 代理對象的創(chuàng)建。

好了,到這里我們的 mapper對象就獲取到了。大家可以想一想,為什么獲取一個 mapper 對象會那么復(fù)雜?或者說 mapper 對象有什么作用?其實就是為了通過 mapper 接口的方法獲取到 mapper.xml 里面的 sql,具體怎么獲取的,請允許阿粉賣個關(guān)子,請聽阿粉下回分解。

3.總結(jié)

最后,阿粉以一個時序圖來結(jié)束本篇文章,喜歡的話,記得點個贊哦。么么噠~


名稱欄目:聊聊Mybatis系列之Mapper接口
瀏覽地址:http://www.5511xx.com/article/dhhhcpe.html