mybatis源码解析-getMapper

之前两篇文章:
mybatis源码解析-SqlsessionFactory
mybatis源码解析-获取Sqlsession
介绍了在mybatis运行中的前两步的执行过程和原理,继续摆出我们的demo:

//1.通过输入流解析xml配置文件
InputStream inputstream = Resources.getResourceAsStream("xxx.xml")
SqlsessionFactory sqlsessionfactory = new SqlsessionFactoryBuilder().build(inputstream);
//2.获取和数据库的链接,创建会话
SqlSession openSession = sqlsessionfactory.openSession();
//3.获取接口的实现类对象,会为接口自动的创建一个代理对象mapper,代理对象会去执行增删改查方法
xxxMapper mapper = openSession.getMapper(xxxMapper.class)
//4.执行增删改的方法

接下来我们聊聊openSession.getMapper(xxxMapper.class)这一步,前面说了,sqlsessionfactory.openSession();返回一个默认的DefaultSqlSessionSqlSession对象,这个对象里面包含Executor和Configuration

getMapper

1.1:直接进入getMapper方法:

public <T> T getMapper(Class<T> type) {
        return this.configuration.getMapper(type, this);
    }

它是调用configuration的getMapper方法:
在这里插入图片描述
在我们之前的介绍中提到过,Configuration是全局配置对象,里面保存了所有配置文件信息以及两个很重要的属性分别如下:
在这里插入图片描述
1.2我们进入mapperRegistry.getMapper方法

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
        if (mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        } else {
            try {
                return mapperProxyFactory.newInstance(sqlSession);
            } catch (Exception var5) {
                throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
            }
        }
    }

代码中写的很明确了,根据接口类型获取MapperProxyFactory,拿到该对象后执行mapperProxyFactory.newInstance(sqlSession);这个方法,我们进入该方法:
1.3

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

    public T newInstance(SqlSession sqlSession) {
        MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
        return this.newInstance(mapperProxy);
    }

我们进入了该方法,发现MapperProxy<T>,继续点进去:
在这里插入图片描述
这个类中有SqlSession,对应接口类型Class<T> mapperInterface,以及方法映射Map<Method, MapperMethod> methodCache,并且该类实现了InvocationHandler,然后调用

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

这个方法,这个方法里用的是反射包下的Proxy对象创建mapperProxy,然后一步步返回
xxxMapper mapper = openSession.getMapper(xxxMapper.class)
最终返回的是代理对象,这个mapper里面封装了sqlsession对象,而sqlsession里面创建了Executor来执行sql语句,因此可以使用这个mapper代理类来实现具体的增删改查操作了

总结:

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章