Mybatis源碼解析5—— 接口代理


本篇文章,可樂將為大家介紹通過接口代理的方式去執行SQL操作。話不多說,直接上圖:

其實無論哪種方式,我們最終是需要找到對應的 SQL 語句,接口代理的方式就是通過 【包名.方法名】 的方式,去找到 xxxMapper.xml 文件中的 SQL 語句。

很明顯,通過動態代理的方式,我們能夠實現該功能。下面,可樂將為大家手擼一個 Mybatis 的接口代理。

1、創建接口

package com.itcoke.mapperproxy;

import com.itcoke.bean.Person;

public interface PersonMapper {

    Person selectPersonById(Long pid);
}

2、創建代理類

package com.itcoke.mapperproxy;

import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MapperProxyHandler implements InvocationHandler {
    private SqlSession sqlSession;
    private Class<?> targetInterface;

    public MapperProxyHandler(SqlSession sqlSession,Class<?> targetInterface){
        this.sqlSession = sqlSession;
        this.targetInterface = targetInterface;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String className = targetInterface.getName();
        String methodName = method.getName();
        String statement = className + "." + methodName;

        return sqlSession.selectOne(statement,args[0]);
    }
}

3、創建代理工廠類

package com.itcoke.mapperproxy;

import java.lang.reflect.Proxy;

public class MapperProxyFactory {
    private Class<?> targetInterface;

    public MapperProxyFactory(Class<?> targetInterface){
        this.targetInterface = targetInterface;
    }

    public Object newInstance(MapperProxyHandler handler){
        return Proxy.newProxyInstance(targetInterface.getClassLoader(),
                new Class[]{targetInterface},
                handler);
    }
}

4、創建測試類

package com.itcoke.mapperproxy;

import com.itcoke.bean.Person;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MapperProxyTest {

    public static void main(String[] args) {
        // 1、獲取目標接口對象
        Class<?> targetInterface = PersonMapper.class;
        // 2、獲取 SqlSession 對象
        SqlSession sqlSession = getSqlSession();
        MapperProxyHandler proxyHandler = new MapperProxyHandler(sqlSession,targetInterface);
        MapperProxyFactory mapperProxyFactory = new MapperProxyFactory(PersonMapper.class);
        PersonMapper personMapper = (PersonMapper)mapperProxyFactory.newInstance(proxyHandler);
        Person person = personMapper.selectPersonById(1L);
        System.out.println(person);
    }



    public static SqlSession getSqlSession() {
        //定義mybatis全局配置文件
        String resource = "mybatis-config.xml";
        //加載 mybatis 全局配置文件
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //構建sqlSession的工廠
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return  sessionFactory.openSession();
    }
}

5、總結

其實 Mybatis 內部實現方式大體上和上面差不多,在加入一些類型處理器,其實就是一個簡易版本的 Mybatis


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM