Mybatis源码阅读系列(一)

12 篇文章 0 订阅
9 篇文章 0 订阅

今天正式开始学习Mybatis的源码,严格来说Mybatis整个体系涉及的项目很多,核心项目是Mybatis3。然后在Mybatis-3上衍生出来和spring集成的Mybatis-Spring。后面SpringBoot出来之后,又创建了一个Mybatis-Spring-Boot-Starter项目,用来在SpringBoot里面对Myabtis进行自动装载,而不需要你导各种包和写很多配置,这个项目都帮你弄好了。

后面文章会将这几个项目的源码都进行源码剖析,里面很多实现细节其实非常值得我们借鉴,特别是mybatis里面的动态代理部分用的十分妙,达到了对用户完全透明的程度,无缝衔接了mapper接口和xml文件之间的对应,你只需要在xml里面指定接口全路径地址,如果没有同名类的话甚至可以只写接口名字就能映射上。

从SqlSessionFactory说起

Mybatis的所有操作其实都是通过SqlSession这个接口来做的,你可以通过它执行sql命令、获取映射器和管理事务。但是我看来它更多的像是一个工具调用类,内部很多细节其实是其他类去实现的。但是这个SqlSession需要利用sqlsessionFactory去创建,这也是框架常用的方式,大部分类都会使用XXXFactory进行创建。

那我们看看Mybatis是如何生成sqlsessionFactory的呢?早期的mybatis其实是使用的xml配置文件构建sqlsessionFactory,官网的示例如下:

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

先读取配置文件,然后利用sqlsessionFactoryBuilder读取配置文件构建sqlsessionFactory,最后用sqlsessionFactory创建sqlsession

看这个你可能不太能看出来它里面类都干了啥,我们换成一个非XML的实现,也是现在myabtis-spring使用的方式,如下:

DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

这时可以比较清晰看出,读取配置文件就是为了拿到datasource,事务配置,和mapper包,然后在解析的时候会将mapper和xml映射起来存着,其实底层就是一个map,在MapperRegistry里面的knownMappers这个Map,后面通过sqlsession.getMapper产生的代理类直接调用。而这里因为没有解析xml,所以需要手动在configuration里面调用addMapper将类放到mapperRegistry里面,以便后面再getMapper的时候能找到。

SqlSession

它是一个接口,在session包下面,这个包定义了整个框架session相关的所有东西。

它基本上是面向用户的窗口。正常我们都是通过操作它去使用mybatis。事实上我们做CRUD用的最多的也是它,可能你会说我咋在项目中基本没看到过它,而且从来没有用过它。原因是你用了spring,myabtis-spring项目很好的将这些封装起来了,你基本不需要用sqlsession,可以直接从spring的ioc容器里面直接拿到mapper接口实现类操作即可。

这个接口有很多方法,实现如下:

在这里插入图片描述

可以看到大部分和CRUD相关,只是参数不同,一部分和事务相关,还有获取连接和获取mapper。几乎所有和mybatis相关的操作你都可以在这里找到。你平时可能就用过getMapper方法,这个都可能还是你自己测试时用的,项目里大多数都是直接注入接口的代理实现就行。可见这个框架封装的真的好,细节你完全不知道也能用。

DefaultSqlSession

SqlSession主要实现类是DefaultSqlSession,它有一个缺点不是线程安全的,所以mybatis-spring弄了一个线程安全的SqlSessionTemplate。

其实Mybatis3里面有一个自己的线程安全sqlsession实现,就是sqlsessionManager,但是我看框架里面好像没有用到,可能是给开发自己去用的吧。因为我们常用的sqlsessionFactory.openSession()都是默认创建的DefaultSqlSession,所以也不知道sqlsessionManager这玩意什么时候用的。

不管SqlSessionTemplate还是sqlsessionManager都是用的同一个东西来实现线程安全的,ThreadLocal,有兴趣可以自己去看下。

这里的所有selectOne和SelectList都是调用的selectList方法。然后一个比较有意思的点是update,insert,delete都是调用的update方法。其实也很好解释,所有RUD都是修改操作,数据库底层认为是一样的。

然后它们都会通过MappedStatement ms = configuration.getMappedStatement(statement);拿到ms,最后由Executor去执行。

这里的Executor是使用的命令模式将所有请求封装起来,然后统一执行。Executor是直接与数据库交互的组件。它被封装在SqlSession里面,外界无感知。它的实现其实很多,对应了不同的ExecutorType。
在这里插入图片描述

其中对外能设置的是三个,Simple,Batch,Reuse。base其实是公共实现,不对外,caching其实就是缓存,所以也不对外。

总结

今天大概理了下Mybatis框架的使用,核心就是利用配置,这个配置可以是XML,也可以是你自己手动创建的Configuration类,然后创建sqlsessionFactory,最后利用sqlsessionFactory得到SqlSession。

Sqlsession是对外统一提供的API接口,它的默认实现是DefaultSqlSession,而整个框架的初始化大部分东西都在Configuration类里,我们明天一起来看下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值