MyBatis 源码分析-- getMapper(获取Mapper)

前言:

前面我们从源码层面梳理了 SqlSessionFactory、SqlSession 的创建过程,本篇我们继续分析一下 Mapper 的的获取过程。

初识 MyBatis 【MyBatis 核心概念】

MyBatis 源码分析--SqlSessionFactory

MyBatis 源码分析--获取SqlSession

案例代码:

java 复制代码
public class MyBatisTest {
    @Test
    public void test() throws IOException {
        //读取配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //创建 SqlSessionFactoryBuilder 对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //通过 SqlSessionBuilder 对象 解析 mybatis-config.xml 文件 构建一个SqlSessionFactory 
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        //通过SqlSessionFactory构建一个SqlSession
        SqlSession session = sqlSessionFactory.openSession();
        //通过SqlSession 获取 Mapper 实例
        UserMapper userMapper = session.getMapper(UserMapper.class);
        //获取数据
		List<User> users = userMapper.findAll();
        //打印输出
        for (User user : users) {
            System.out.println(user);
        }
        //关闭资源
        session.close();
        is.close();
    }
}

本篇我们将主要对 session.getMapper(UserMapper.class); 这句代码进行分析。

DefaultSqlSession#getMapper 源码分析

java 复制代码
//org.apache.ibatis.session.defaults.DefaultSqlSession#getMapper
public <T> T getMapper(Class<T> type) {
	return this.configuration.getMapper(type, this);
}


//org.apache.ibatis.session.Configuration#getMapper
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
	return this.mapperRegistry.getMapper(type, sqlSession);
}

MapperRegistry#getMapper 源码分析

java 复制代码
//org.apache.ibatis.binding.MapperRegistry#getMapper
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
	//根据 class 获取 Mapper 代理工厂
	MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
	if (mapperProxyFactory == null) {
		throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
	} else {
		try {
			//使用 Mapper 代理工厂创建 Mapper 代理对象返回
			return mapperProxyFactory.newInstance(sqlSession);
		} catch (Exception var5) {
			throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
		}
	}
}

//org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.session.SqlSession)
public T newInstance(SqlSession sqlSession) {
	//Mapper 代理
	MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
	//创建 Mapper 代理对象
	return this.newInstance(mapperProxy);
}


//org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.binding.MapperProxy<T>)
protected T newInstance(MapperProxy<T> mapperProxy) {
	//使用 JDK 创建一个 Mapper 的代理对象
	return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}

从源码可以看出,获取 Mapper 其实就是根据 Mapper 的 Class 类型从 MapperRegistry 中获取一个 MapperProxyFactory,最终调用 MapperProxyFactory.newInstance 方法创建一个代理对象,生成一个代理类来调用 Mapper 的方法,这里的 MapperProxyFactory 其实就是在获取 SqlSessionFactory 中存入 MapperRegistry 的 MapperProxyFactory。

欢迎提出建议及对错误的地方指出纠正。

相关推荐
坐不住的爱码8 分钟前
mybatis-动态sql语句-<foreach>
java·sql·mybatis
风月歌39 分钟前
小程序项目之驾校报名小程序源代码(java+vue+小程序+mysql)
java·vue.js·mysql·小程序·毕业设计·源码
0和1的舞者1 小时前
《MyBatis 从入门到上手:超全基础操作 + XML 配置指南》
数据库·spring boot·学习·spring·mybatis·框架·开发
风月歌1 小时前
小程序项目之使命召唤游戏助手源代码(java+vue+小程序+mysql)
java·mysql·小程序·毕业设计·源码
过期动态1 小时前
JDBC进阶篇:拓展功能与连接池运用详解
java·开发语言·数据库·mysql·oracle·intellij-idea·mybatis
期待のcode7 小时前
MyBatisX插件
java·数据库·后端·mybatis·springboot
小二·14 小时前
MyBatis基础入门《十五》分布式事务实战:Seata + MyBatis 实现跨服务数据一致性
分布式·wpf·mybatis
小二·14 小时前
MyBatis基础入门《十四》多租户架构实战:基于 MyBatis 实现 SaaS 系统的动态数据隔离
数据库·架构·mybatis
小二·19 小时前
MyBatis基础入门《十六》企业级插件实战:基于 MyBatis Interceptor 实现 SQL 审计、慢查询监控与数据脱敏
数据库·sql·mybatis
小二·19 小时前
MyBatis基础入门《十二》批量操作优化:高效插入/更新万级数据,告别慢 SQL!
数据库·sql·mybatis