> ### 架构图
![](https://i.loli.net/2019/03/14/5c89299206be0.png)
<br/>
![](https://i.loli.net/2019/03/15/5c8b62b51fc6a.png)
<br/>
> ### `Mybatis`缓存
* **一级缓存**
![](https://i.loli.net/2019/03/15/5c8b67583cde7.png)
* `SqlSession`将它的工作交给了`Executor`执行器这个角色来完成,负责完成对数据库的各种操作。当创建了一个`SqlSession`对象时,`MyBatis`会为这个`SqlSession`对象创建一个新的`Executor`执行器,而缓存信息就被维护在这个`Executor`执行器中.。
* 当会话结束时,`SqlSession`对象及其内部的`Executor`对象还有`PerpetualCache`对象也一并释放掉。
* 如果`SqlSession`调用了`close()`方法,会释放掉一级缓存`PerpetualCache`对象,一级缓存将不可用。
* 如果`SqlSession`调用了`clearCache()`,会清空`PerpetualCache`对象中的数据,但是该对象仍可使用。
* `SqlSession`中执行了任何一个`update`操作(update()、delete()、insert()) ,都会清空`PerpetualCache`对象的数据,但是该对象可以继续使用。
* `MyBatis`的一级缓存就是使用了简单的`HashMap`,`MyBatis`只负责将查询数据库的结果存储到缓存中去, 不会去判断缓存存放的时间是否过长、是否过期。
* `Mybatis`默认开启一级缓存。如果`Mybatis`与`Spring`整合了,`Spring`会自动关闭`sqlSession`。所以一级缓存也会失效。`Spring`每次查询数据都会新建一个`sqlSession`绑定到当前线程的`ThreadLocal`,执行完查询之后关闭`sqlSession`并情况`ThreadLocal`。
* **二级缓存**
![](https://i.loli.net/2019/03/15/5c8b6ad3148b3.png)
* 当开一个会话时,一个`SqlSession`对象会使用一个`Executor`对象来完成会话操作,`MyBatis`的二级缓存机制的关键就是对这个`Executor`对象做文章。如果用户配置了`"cacheEnabled=true"`,那么`MyBatis`在为`SqlSession`对象创建`Executor`对象时,会对`Executor`对象加上一个**装饰者**:`CachingExecutor`,这时`SqlSession`使用`CachingExecutor`对象来完成操作请求。
* `CachingExecutor`对于查询请求,会先判断该查询请求在`Application`级别的二级缓存中是否有缓存结果,如果有查询结果,则直接返回缓存结果;如果缓存中没有,再交给真正的`Executor`对象来完成查询操作,之后`CachingExecutor`会将真正`Executor`返回的查询结果放置到缓存中,然后在返回给用户。
* 如果你的`MyBatis`使用了二级缓存,在执行查询时会优先从二级缓存获取。
* `MyBatis`对二级缓存的设计非常灵活,内部实现了一系列的`Cache`缓存实现类,并提供了各种缓存刷新策略如`LRU`,`FIFO`。`Mybatis`也支持自定义缓存如`Redis`等。
<br/>
> ### 动态`SQL`
* `if`
```xml
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
```
* `choose, when, otherwise`
```xml
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
```
* `trim, where, set`
```xml
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
```
```xml
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
```
* `foreach`
```xml
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
```
***
参考:
[《深入理解mybatis原理》 MyBatis的一级缓存实现详解](https://blog.csdn.net/luanlouis/article/details/41280959)
[《深入理解mybatis原理》 MyBatis的二级缓存的设计原理](https://blog.csdn.net/luanlouis/article/details/41408341)
[Mybatis的缓存](https://www.jianshu.com/p/c553169c5921)
[MyBatis的架构设计以及实例分析](http://www.cnblogs.com/KingIceMou/p/7193769.html)
- asD
- Java
- Java基础
- Java编译器
- 反射
- collection
- IO
- JDK
- HashMap
- ConcurrentHashMap
- LinkedHashMap
- TreeMap
- 阻塞队列
- java语法
- String.format()
- JVM
- JVM内存、对象、类
- JVM GC
- JVM监控
- 多线程
- 基础概念
- volatile
- synchronized
- wait_notify
- join
- lock
- ThreadLocal
- AQS
- 线程池
- Spring
- IOC
- 特性介绍
- getBean()
- creatBean()
- createBeanInstance()
- populateBean()
- AOP
- 基本概念
- Spring处理请求的过程
- 注解
- 微服务
- 服务注册与发现
- etcd
- zk
- 大数据
- Java_spark
- 基础知识
- Thrift
- hdfs
- 计算机网络
- OSI七层模型
- HTTP
- SSL
- 数据库
- Redis
- mysql
- mybatis
- sql
- 容器
- docker
- k8s
- nginx
- tomcat
- 数据结构/算法
- 排序算法
- 快排
- 插入排序
- 归并排序
- 堆排序
- 计算时间复杂度
- leetcode
- LRU缓存
- B/B+ 树
- 跳跃表
- 设计模式
- 单例模式
- 装饰者模式
- 工厂模式
- 运维
- git
- 前端
- thymeleaf
- 其他
- 代码规范
- work_project
- Interview