Mybatis简介
Mybatis是一款优秀的持久层框架,在国内而言还是比较受欢迎的,无论是分布式还是微服务还是兴起的云原生在与数据库的交互这一层大多数人还是会很愿意使用Mybaits来集成的,它有丰富的社区以及各种场景的现有解决方案,已经很成熟,所以翻阅一下它的源码知道其运行原理是很有价值必要的。
Mybatis的架构
其实Mybatis的源码很简单,架构设计也清晰明了,作为与数据库直接交互的一层,本质就是调用的java与数据库厂商之间的驱动去做事情,相信学习过java的同学们一定都非常了解我们调用原生驱动的时候怎样连接数据库,无非就是注册驱动,获取连接,准备statement语句(预处理),然后执行获取resultSet对结果进行处理,如果考虑性能可以上一个连接池,比如阿里巴巴的德鲁伊,Mybatis也是这样处理的,它无非就是在这上边封装了一层很丰富健全的功能,让这一套更加简单好用,所以我们只要把握住本质然后去阅读就会省很多事情。
源码包对应的架构图
- 接口
session包是mybatis开发给外界的调用接口,诸如SqlSessionFactoryBuilder、SqlSession、SqlSessionManager等,我们可以通过SqlSession去操控Mybatis
@Test
public void test() throws Exception {
InputStream resourceAsStream = Resources.getResourceAsStream("org/apache/ibatis/test/SqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = build.openSession();
User user = sqlSession.<User>selectOne("userMapper.selectUserByName", "zs");
}
- 核心层
- builder
builder,构建者模式,是mybatis用来解析xml的一个核心包,类似工地工头一样,是统领解析工作进行的主导者,主要有XMLConfigBuilder(构建解析config配置的)、XMLMapperBuilder(构建解析mapper的)、XMLStatementBuilder(构建sql语句)、MapperAnnotationBuilder(构建注解方式) - parsing
这部分主要是解析xml中的节点以及对sql语句中类似#{}这样的替代福替换的,XPathParser与XNode会将mybatis的每一个节点解析成为Xnode,这样全局统一其实操作起来更加便捷,GenericTokenParser设计比较巧妙,它是负责替换解析类似#{}这样的标识符的,之后详解。 - mapping
mapping包的功能主要是对cofnig以及mapper中信息的映射存储,类似ResultMap(返回结果信息映射)、ParameterMap(入参信息映射)、Discriminator(分词)等 - plugin
plugin包的功能主要是对mybatis的plugin的管理,InterceptorChain责任链模式,会对Executor、StatementHandler、PameterHandler和ResultSetHandler 等进行拦截 - type
type包下有对应java各种类型的handler处理器,mybatis会默认将这些处理器注册上来,在处理过程中会先对参数数据类型进行判断然后交由各自对应的handler去处理 - scripting
scripting包下是对sql的脚本处理,在mapper中配置的一个sql语句最终会被解析成一个个的sqlNode,例如动态sql if 会被处理成IfSqlNode这样的节点、foreach会被处理成ForEachSqlNode这样的节点。 - annotations
annotations包下有mybatis所有的注解,注入Insert、Delete、Select等 - jdbc
jdbc是为provider类型的注解服务的,provider类中的SQL就在这个包下 - cursor
cursor是游标,这个包下有操作数据库游标的相关类 - executor
mybatis中executor是核心,由它去调度各种资源完成数据库的相关操作。executor包下有PreparedStatementHandler(对statement的调用处理)、DefaultResultSetHandler(对查询结果resultSet的处理)、Jdbc3KeyGenerator(insert时的主键生成)等。 - binding
binding包下是对mapper的代理,如果我们使用的是SqlSession的getMapper方法,则会去通过MapperProxyFactory这个工厂去创建一个MapperProxy代理类去执行相应的方法。 - datasources
datasources包是mybatis的数据源管理,mybatis有个简单的连接池Pooled。 - transaction
mybatis对事物的相关操作都在这里。
- 公用
- logging
mybatis有自己的一套日志处理方式并且是兼容多种日志处理框架的集成,有log4j、slf4j等 - io
MyBatis里的IO主要是包含两大功能:提供读取资源文件的API、封装MyBatis自身所需要的ClassLoader和加载顺序。 - exceptions
MyBatis自己对异常的处理 - reflection
reflection包下是mybatis对反射的相关封装类,主要有MetaObject、MetaClass、Reflector、wrapper等,其实mybatis之所以可以将返回结果封装成pojo实体类,都是通过reflection包下的相关类通过反射去完成这个操作的,所以这个包下的类相对而言也是非常重要的。