成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊Mybatis系列之Mapper接口

開發 開發工具
了解一個類,首先看下成員變量和構造方法。這里 config 不用多說了吧,主要的是 knownMappers 這個成員變量。這就是個map 對象,只是這個 map 對象的 value值是個對象,所以又要去看下 MapperProxyFactory 這個對象。

[[327761]]

 1.上期回顧

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

  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 一級緩存的實現原理。這次,我們來了解下 mybatis 接口的創建。

2. mapper接口的創建流程

2.1 SqlSession的getMapper()

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

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

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

2.2 Configuration 的getMapper()

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

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

2.3 MapperRegistry 的getMapper()

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

  1. public <T> T getMapper(Class<T> type, SqlSession sqlSession) { 
  2.     final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) 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<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>(); 
  5.  
  6.   public MapperRegistry(Configuration config) { 
  7.     this.config = config; 
  8.   } 
  9.     ... 

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

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

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

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

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

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

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

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

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

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

3.總結

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

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2022-10-20 18:00:00

MyBatis緩存類型

2022-06-02 07:11:13

JVMJava

2020-12-08 12:24:55

接口測試Interface

2021-01-14 10:00:57

Restful接口

2021-12-09 12:22:28

MyBatis流程面試

2023-09-21 08:05:49

Mybatis插件開發

2021-09-18 09:45:33

前端接口架構

2023-11-20 08:01:38

并發處理數Tomcat

2021-07-11 12:12:49

.NETJWTjson

2023-07-26 07:13:55

函數接口Java 8

2024-06-12 08:36:25

2025-01-16 10:30:49

2021-06-07 08:39:58

SpringBootMyBatisMapper

2022-12-28 08:16:16

metric聚合java

2022-01-26 00:05:00

接口Spring管理器

2022-11-17 07:43:13

2022-07-11 09:00:37

依賴配置文件Mybati

2022-02-08 23:59:12

USB接口串行

2022-01-10 11:28:55

數據結構算法DP入門

2025-01-07 09:07:36

接口屬性路徑
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜小影院 | 岛国毛片在线观看 | 99免费在线视频 | 在线看片福利 | 一区二区三区影院 | 国产精品久久久久久av公交车 | 一区二区三区高清不卡 | 日操夜操 | 亚洲午夜电影 | 男女视频在线观看网站 | 欧美日韩不卡合集视频 | 国产免费又色又爽又黄在线观看 | 91精品久久久久久久久 | 精品美女视频在线观看免费软件 | 日韩精品视频一区二区三区 | 男人天堂网址 | 亚洲欧美一区二区三区国产精品 | 成人福利影院 | 福利片在线看 | 91资源在线 | 91在线精品秘密一区二区 | 国产人成精品一区二区三 | 一区中文字幕 | 午夜免费视频 | 欧美一区二区在线播放 | 国产99视频精品免费视频7 | 欧美在线观看一区 | 日韩一区二区三区av | 中文字幕日韩三级 | 亚洲国产精品人人爽夜夜爽 | 欧美成人免费 | 亚洲三级av| 免费一级片 | 91大神在线看 | 亚洲视频免费观看 | 欧美涩涩网 | 中文字幕一区二区三区在线观看 | 在线观看日韩精品视频 | 狠狠干在线 | 久久久久久成人 | 国产一区二区在线免费观看 |