MyBatis(三)-----源码解析(一)

该博客从编程式 demo 入手分析 MyBatis 源码,分四步进行:第一步用建造者模式创建工厂类,完成配置文件解析,得到 Configuration 对象和 DefaultSqlSessionFactory;第二步通过 SqlSessionFactory 创建 SqlSession;第三步获得 Mapper 对象,实质是 MapperProxy 代理对象;第四步调用接口方法,介绍了其与 XML 映射器中 StatementID 的关联。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分析源码,我们还是从编程式的 demo 入手

 InputStream inputStream = Resources.getResourceAsStream(resource);
//步骤1
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//步骤2
        SqlSession session = sqlSessionFactory.openSession(); 
//步骤3
            BlogMapper mapper = session.getMapper(BlogMapper.class);
//步骤4
            Blog blog = mapper.selectBlogById(1);

把文件读取成流的这一步我们就省略了。所以下面我们分成四步来分析.

1.第一步

 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

我们通过建造者模式创建一个工厂类,配置文件的解析就是在这一步完成 的,包括 mybatis-config.xml 和 Mapper 适配器文件。
问题:解析的时候怎么解析的,做了什么,产生了什么对象,结果存放到了哪里。 解析的结果决定着我们后面有什么对象可以使用,和到哪里去取。
答:在这一步,我们主要完成了 config 配置文件、Mapper 文件、Mapper 接口上的注 解的解析。 我们得到了一个最重要的对象 Configuration,这里面存放了全部的配置信息,它在 属性里面还有各种各样的容器。 最后,返回了一个 DefaultSqlSessionFactory,里面持有了 Configuration 的实例。

2.第二步

 SqlSession session = sqlSessionFactory.openSession();

通过 SqlSessionFactory 创建一个 SqlSession。
问题:SqlSession 是用来操作数据库的,返回了什么实现类,除了 SqlSession,还 创建了什么对象,创建了什么环境?
答:创建会话的过程,我们获得了一个 DefaultSqlSession,里面包含了一个 Executor,它是 SQL 的执行者。

3.第三步

 BlogMapper mapper = session.getMapper(BlogMapper.class);

获得一个 Mapper 对象。
问题:Mapper 是一个接口,没有实现类,是不能被实例化的,那获取到的这个 Mapper 对象是什么对象?为什么要从 SqlSession 里面去获取?为什么传进去一个接 口,然后还要用接口类型来接收?
答:
现在我们已经有一个 DefaultSqlSession 了,必须找到 Mapper.xml 里面定义的 Statement ID,才能执行对应的 SQL 语句。 找到 Statement ID 有两种方式:一种是直接调用 session 的方法,在参数里面传入 Statement ID,这种方式属于硬编码,我们没办法知道有多少处调用,修改起来也很麻 烦。另一个问题是如果参数传入错误,在编译阶段也是不会报错的,不利于预先发现问 题

Blog blog = (Blog) session.selectOne("com.gudu.mapper.BlogMapper.selectBlogById ", 1);

所以在 MyBatis 后期的版本提供了第二种方式,就是定义一个接口,然后再调用 Mapper 接口的方法。 由于我们的接口名称跟 Mapper.xml 的 namespace 是对应的,接口的方法跟 statement ID 也都是对应的,所以根据方法就能找到对应的要执行的 SQL。

BlogMapper mapper = session.getMapper(BlogMapper.class);

总结:
获得 Mapper 对象的过程,实质上是获取了一个 MapperProxy 的代理对象。 MapperProxy 中有 sqlSession、mapperInterface、methodCache

第四步

 Blog blog = mapper.selectBlogById(1);

调用接口方法。
问题:我们的接口没有创建实现类,为什么可以调用它的方法?那它调用的是什么 方法?它又是根据什么找到我们要执行的 SQL 的?也就是接口方法怎么和 XML 映射器 里面的 StatementID 关联起来的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值