SqlSession下的四大对象
Executor:执行器
StatementHandler:封装jdbc的statement执行Sql
ParameterHandler:Sql参数处理
ResultHandler:结果封装
前期准备
mybatis的起始操作都是在操作SqlSession,阅读源码时,以此为突破口。
1、获取Mapper对象
工程启动时将扫描到的mybatis mapper接口添加到map集合里
2、将解析好的MapperMethod,添加到map集合methodCache中
3、使用autowired或者其他方式触发装载时,将mapper接口从map中取出并实例化为一个MapperProxy对象。
4、将xml中的方法解析成MappedStatement对象放入mappedStatements 注意:无法对mapper的接口方法进行重载,xml中方法的定位时根据类名+方法名定位的
SqlSession 执行
1、执行mapper的方法即为执行代理MapperProxy的invoke方法
2、取出对应的MapperMethod方法
3、执行MapperMethod方法
发现中途执行了代理类
4、根据id(类名+方法名)找到xml中方法封装成的MappedStatement对象
5、调用Executor执行查询
6、SQL参数处理
7、使用Statement执行sql
8、使用ResultHandler封装结果集
利用反射通过构造函数构造生成实例
在没有在xml中显示使用构造函数的情况下,默认使用无参构造函数创建实例,若没有无参构造函数会抛出异常
赋值根据反射获取属性的set方法赋值,没有set方法抛出异常
延迟加载
延迟加载只适用使用association和collection的嵌套查询,关联查询不会触发延迟加载。
lazyLoadingEnabled:true
aggressiveLazyLoading: false 侵入式延迟加载:
使用任何数据包括主数据就会触发查询。
aggressiveLazyLoading: true 深度延迟加载:
只有使用到关联数据才会触发查询。
使用动态代理封装返回结果,在调用get,clone,equals,toString等方法时,判断是否已经加载过,未加载过则执行sql查询
缓存
一级缓存(本地缓存)
localCacheScope:session/statement
一次sql会话中,执行多次完全完全相同的sql,会命中一级缓存
mbatis默认开启一级缓存,默认级别为session,在分布式环境下可能会产生脏数据,建议使用statement。
BaseExecutor.localCache HashMap维护 key:CacheKey 根据类名+方法名+偏移量offset+limit+sql组成
在执行Insert、Update、Delete后会清空缓存
二级缓存
CachingExecutor
多个sqlSession在同一个namespace之间共享缓存,也可以通过cache-ref关联 其他的namespace
只有sqlsession提交后才会进入缓存,表空间中涉及任何的delete\update\insert操作提交都会清除缓存。
不同表空间操作同一个表的数据容易产生脏数据。