MyBatis 原理
MyBatis 整体结构
配置文件
配置类提供的功能几乎贯穿了整个处理过程:
- 解析 Xml 文件
- 创建 SQL 处理器 Executor
- 对语句进行缓存 MappedStatement
怎么定位路径
- getResourceAsStream
怎么解析文件
xml 文件的解析方式有两种,一种 DOM 是直接读入整个 xml 文件,根据标签的嵌套关系构建一棵文档树;另一种方式叫 SAX(Simple API for XML),是一种事件驱动的文档解析方式,什么是事件驱动呢?比如说 SAX 驱动扫描到了起始标签,就代表发生了一个事件,它会转而调用某个由用户定义的函数(startElement)执行逻辑。
有一种设计原则叫好莱坞法则(Hollywood),形象地说就是“你不要 call 我,需要你时我会 call 你”,一个例子是异步调用,这是一种通信机制,客户端在发出请求后不必等待服务端处理完毕就可以返回处理自己的逻辑,等到服务端处理完毕后再将结果传回,这种方式一定程度上可以解决客户端长期阻塞的问题、改善用户体验,回调函数也是一个例子。
据网上的说法,DOM 需要一次构建整棵 DOM 树,所以比较占内存,不适合大的 xml 文档解析,但是由于 DOM 树上可以任意遍历,所以自由度很高,相对来说,SAX 是读到什么就调用什么回调函数,所以内存占用小,但是编程多少会复杂一些。
构建数据库连接
数据库连接
SqlSessionFactoryBuilder
应用了建造者模式,根据配置文件来创建 SqlSessionFactory,创建后其任务就结束了,生命周期在一个方法内。
SqlSessionFactory
创建和数据库连接的工具,在整个应用运行期间应该作为一个单例存在,或者使用依赖注入管理其生命周期。
SqlSession
代表和数据库的一次连接,在 MyBatis 中其实现是线程不安全的,生命周期最好控制在一次请求之间。
数据源
- DBCP
- C3P0
- Druid
- MyBatis 内置数据源(UNPOOLED、POOLED、JNDI)
- 自定义数据源
映射器
- mapper 文件
- 注解
SQL 执行
SqlSession 本身是可以直接执行 sql 语句的,它的所有 update、query 等方法都是对语句进行了包装(MappedStatement),然后再调用 Executor 的相应方法,Executor 是执行器,是 MyBatis 的核心。
SQL 的执行是由 Executor 负责的,Executor 对象是和 SqlSession 同时创建的,SqlSessionFactory 会为 Executor 创建事务,事务类默认为 ManagedTransactionFactory,Executor 需要从事务对象获取数据库连接(包装上一层事务后扩展性更好),事务会从环境对象中获取 DataSource 对象,然后委托 DataSource 创建连接,并且可以根据事务等级来为连接设置事务。说白了,把 Config 对象传给新建的 Transaction,由 Transaction 创建连接。
Executor 并不是直接执行 SQL 语句,SQL 语句由 MappedStatement 包装,再交给 StatementHandler 执行