說明java
MyBatis版本:3.5.1sql
相關歷史文章(閱讀本文以前,您可能須要先看下以前的系列)session
Spring Boot MyBatis最全教程:你值得擁有
MyBatis能脫離Spring嗎一圖縱覽MyBatis的工做原理從源碼看MyBatis,竟如此簡單MyBatis的Mapper是什麼`垃圾` mybatis
手寫MyBatis,純手工打造開源框架(第一篇:風雲再起) app
手寫MyBatis,純手工打造開源框架(第二篇:君臨天下) 框架
手寫MyBatis,純手工打造開源框架(第三篇:指揮若定) 測試
前言ui
指揮若定之中,決勝千里以外,是該作個告終了,把你的傢伙掏出來,上刺刀。this
上一篇已經可以使用SqlSession進行查詢返回結果了。這一篇咱們就是加入瑞士軍刀Mapper。編碼
1、分析
在SqlSession會提供getMapper的方法,在DefaultSqlSession會使用Proxy實例化一個MapperProxy代理,而MapperProxy代理會獲取SqlSession,在這裏進行Sql的操做,而後結果。
2、編碼
2.1 MapperProxy
MapperProxy是mapper最終執行的核心:
package com.kfit.mybatis.session.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Collection; import com.kfit.mybatis.session.SqlSession; public class MapperProxy implements InvocationHandler{ private SqlSession sqlSession; public MapperProxy(SqlSession sqlSession) { this.sqlSession = sqlSession; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String statement = method.getDeclaringClass().getName()+"."+method.getName(); //isAssignableFrom方法是判斷是否爲某個類的父類 if(Collection.class.isAssignableFrom(method.getReturnType())) { //返回值是集合的話,那麼是調用selectList return sqlSession.selectList(statement,null==args?null:args[0]); }else { return sqlSession.selectOne(statement,null==args?null:args[0]); } } }
說明:
(1)因爲MapperProxy是一個代理類,因此須要實現接口InvocationHandler的Invoke方法。
(2)在Invoke方法中直接使用SqlSession進行執行,那麼主要的核心就是要判斷具體執行什麼方法,這裏如今經過返回值是不是集合來判斷是不是執行selectOne仍是SelectList。
2.2 SqlSession
在SqlSession中添加getMapper方法:
public interface SqlSession { <T> T selectOne(String statement, Object parameter); <E> List<E> selectList(String statement); <E> List<E> selectList(String statement, Object parameter); <T> T getMapper(Class<T> type); }
在DefaultSqlSession中進行實現getMapper方法:
@SuppressWarnings("unchecked") public <T> T getMapper(Class<T> type) { T newProxyInstance = (T) Proxy.newProxyInstance(type.getClassLoader(),new Class[]{type},new MapperProxy(this)); return newProxyInstance; }
2.3 測試下
好了寫段代碼測試下吧:
public static void main(String[] args) { String resource = "mybatis-config.xml"; InputStream inputStream = App.class.getClassLoader().getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); System.out.println(sqlSessionFactory); System.out.println(sqlSessionFactory.getConfiguration().getJdbcProperties().getUrl()); SqlSession sqlSession = sqlSessionFactory.openSession(); Demo demo = null; List<Demo> demos = null; //使用Mapper DemoMapper demoMapper = sqlSession.getMapper(DemoMapper.class); demo = demoMapper.getById(1); System.out.println(demo); demos = demoMapper.getAll(); System.out.println(demos); }
運行看下結果:
Demo [id=1,name=張三1]
[Demo [id=1, name=張三1], Demo [id=9, name=張三], Demo [id=10, name=張三], Demo [id=11, name=張三], Demo [id=12, name=張三], Demo [id=13, name=張三]]
很明顯執行的結果和直接使用SqlSession調用的結果是同樣的。
好了有關手寫MyBatis的文章就先到此告一段落了,經過手寫mybatis,想必你們對於MyBatis的認知又高了一個等級了。
我就是我,是顏色不同的煙火。
我就是我,是不同凡響的小蘋果。
à悟空學院:http://t.cn/Rg3fKJD
學院中有Spring Boot相關的課程!點擊「閱讀原文」進行查看!
SpringBoot視頻:http://t.cn/R3QepWG
Spring Cloud視頻:http://t.cn/R3QeRZc
SpringBoot Shiro視頻:http://t.cn/R3QDMbh
SpringBoot交流平臺:http://t.cn/R3QDhU0
SpringData和JPA視頻:http://t.cn/R1pSojf
SpringSecurity5.0視頻:http://t.cn/EwlLjHh
Sharding-JDBC分庫分表實戰:http://t.cn/E4lpD6e