主要总结一下 mybaitis 的基础配置,基本特性,最后简单分析一下 sqlsession 的原理,了解了运行过程。
简单配置介绍#
简单来说,Mybatis 的配置主要分为以下几步:
- 编写 POJO 即 JavaBean,最终的目的是将数据库中的查询结果映射到 JavaBean 上;
- 配置与 POJO 对应的 Mapper 接口:里面有各种方法,对应 mapper.xml 中的查询语句;
- 配置与 POJO 对应的 XML 映射:编写缓存,SQL 查询等;
- 配置 mybatis-config.xml 主要的 Mybatis 配置文件:配置数据源、扫描 mapper.xml 等。
注意:以上的配置并没有严格的前后顺序;
借用一个比较清晰的配置流程图
可以看出 mapper 接口实现类的获得是通过 mybatis-config.xml->SqlSessionFactoryBuilder->SqlSessionFacotry->SqlSession->mapper
生命周期#
- SqlSessionFactoryBuilder:作用就是创建一个构建器,一旦创建了
SqlSessionFactory
,它的任务就算完成了,可以回收。 - SqlSessionFactory:作用是创建
SqlSession
,而SqlSession
相当于 JDBC 的一个Connection
对象,每次应用程序需要访问数据库,我们就要通过SqlSessionFactory
创建一个SqlSession
,所以SqlSessionFactory
在 Mybatis 整个生命周期中存在(每个数据库对应一个SqlSessionFactory
,是单例产生的)。 - SqlSession:生命周期是存在于请求数据库处理事务的过程中,是一个线程不安全的对象(在多线程的情况下,需要特别注意),即存活于一个应用的请求和申请,可以执行多条 SQL 保证事务的一致性。
- Mapper:是一个接口,并没有实现类。它的作用是发送 SQL,返回我们需要的结果或者发送 SQL 修改数据库表,所以它存活于一个
SqlSession
内,是一个方法级别的东西。当SqlSession
销毁的时候,Mapper 也会销毁。
基础特性#
延迟加载#
即系统延迟执行查询,一般用于嵌套查询的时候,嵌套在内的 SQL 查询会延迟加载,等到真正需要使用该查询的时候才加载。就像懒人你说一下,他动一下,绝不会多执行半步,因此该特性也称之为懒加载。
懒加载必须配置config.xml
,并且只能通过association
或collection
实现,毕竟只有在存在映射关系的业务场景里你需要使用懒加载
配置语句
<settings>
<setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/>
</settings>
使用时需要注意延迟加载必须使用 resultMap,resultType 不具有延迟加载功能。
一级缓存#
- 系统默认开启,缓存的范围为一个
SqlSession
- 只有一个 SqlSession 下的相同查询才会应用缓存,不同 sqlSession 下的即使查询相同一级缓存也不会生效
二级缓存#
-
解决
SqlSession
相互隔离的情况,缓存范围为一个Mapper
接口 -
二级缓存默认是不开启的,需要进行配置,Mybatis 要求返回的 POJO 必须是可序列化的,即 POJO 实现 Serializable 接口。
-
缓存的配置只需要在
XML
配置<cache/>
即可,或者指定算法,刷新时间间隔,缓存状态,大小等例:
- 映射语句文件中所有 select 语句将会被缓存;
- 映射语句文件中所有 insert、update 和 delete 语句会被刷新缓存;
- 缓存使用默认的 LRU 最近最少使用算法回收;
- 根据时间表,缓存不会任何时间顺序刷新
- 缓存会存储列表集合或对象的 1024 个引用
- 缓存被视为可 read/write 的缓存,意味着是不可以被共享的,而可以被安全地修改。
自定义缓存#
通过 Mybatis 实现的接口,使用 redis 等进行缓存
实践配置#
待补充
SqlSession 原理#
SqlSession
提供 select/insert/update/delete 方法
映射器(Mapper
)其实就是一个动态代理对象,进入到MapperMethod
的execute
方法就能简单找到SqlSession
的删除、更新、查询、选择方法.
从底层实现来说:通过动态代理技术,让接口跑起来,之后采用命令模式,最后还是采用了SqlSession
的接口方法(getMapper()
方法等到Mapper
)执行 SQL 查询(也就是说 Mapper 接口方法的实现底层还是采用SqlSession
接口方法实现的)。
SqlSession 重要的四个对象
- Execute:调度执行
StatementHandler
、ParmmeterHandler
、ResultHandler
执行相应的 SQL 语句; - StatementHandler:使用数据库中
Statement(PrepareStatement)
执行操作,即底层是封装好了的prepareStatement
- ParammeterHandler:处理 SQL 参数
- ResultHandler:结果集 ResultSet 封装处理返回。
SqlSession 的四大对象#
Execute#
起 java 和数据库交互桥梁的作用,参与整个 SQL 执行过程。分类
- SIMPLE 简易执行器(默认)
- REUSE 重用预处理执行器
- BATCH 批量更新、批量专用处理器
源码
package org.apache.ibatis.session;
public enum ExecutorType { SIMPLE, REUSE, BATCH}
作用
调度其他对象,完成预编译、配置参数和返回结果集
StatementHanlde#
分类(分别对应不同执行器)
- SimpleStatementHandler
- PrepareStatementHandler
- CallableStatementHandler
作用
专门处理数据库会话。进行预编译并调用 ParameterHandler 配置参数。大致来讲只是对数据库的连接做了封装
工作流程
- 通过调用RoutingStatementHandler对象生成 StatemenetHandler
- RoutingStatementHandler 查找相应的 statementHandler 对象
- statementHandler 调用数据库的方法
ParameterHandler#
作用
对预编译的参数进行设置
工作流程
- 从 parameterObject 中取到参数,然后使用 typeHandler(注册在 Configuration 中)进行参数处理
ResultSetHandler#
作用
组装结果返回结果集
运行过程总结#
- prepare 预编译
- parameterize 设置参数
- doUpdate/doQuery 执行 SQL
神人的总结
参考链接