mybatis
一. mybatis执行流程
理解了各个组件的关系
Sql的执行过程(参数映射、sql解析、执行和结果处理)
二. mybatis支持延迟加载
1. 立即加载
查询用户信息的同时也可以查询到相关订单信息
UserMapper:
OrderMapper:
UserTest.java 打印输出用户信息
执行结果:
2. 延迟加载
fetchType="lazy" 开启局部延迟加载
UserMapper:
UserTest.java 打印输出用户信息
执行结果:先调用查询用户信息,然后因为调用了getOrderList(),所以还执行了查找对应订单的sql
在配置文件中开启全局延迟加载:
3. 延迟加载的原理
使用CGLIB创建目标对象的代理对象
调用目标方法user.getOrderList)时,进入拦截器invoke方法,发现user.getOrderList()是null值,执行sql查询order列表3.把order查询上来,然后调用user.setOrderList(List orderList),接着完成user.getOrderList()方法的调用
4. 问题总结
三. mybatis一级与二级缓存
● 本地缓存:基于PerpetualCache,本质是一个HashMap
● 一级缓存:作用域是session级别
● 二级缓存:作用域是namespace和mapper的作用域,不依赖于session
1. 一级缓存
一级缓存:基于PerpetualCache的 HashMap本地缓存,其存储作用域为Session,当Session进行flush或close之后,该Session中的所有Cache就将清空,默认打开一级缓存
因为这两个都是查询的同一个id的用户信息,所以第二次查询的时候直接在缓存中取,而不需要再次执行SQL语句
2. 二级缓存
二级缓存是基于namespace和mapper的作用域起作用的,不是依赖于SQL session,默认也是采用PerpetualCache,HashMap存储(默认关闭)
开启二级缓存的两个步骤:
1. 全局配置文件
2. 映射文件:使用
3. 执行结果:只调用了一次SQL
注意事项:
- 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了新增、修改、删除操作后,默认该作用域下所有select中的缓存将被clear
- 二级缓存需要缓存的数据实现Serializable接口
- 只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中、