手寫MyBatis,純手工打造開源框架(第四篇:決勝千里)- 第272篇

說明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

相關文章
相關標籤/搜索