type
status
date
slug
summary
tags
category
icon
password
URL
文章来源说明
动态sql
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
- bind
- sql片段
1、if
EmpDao.xml
EmpDao.java
Test
看起来测试是比较正常的,但是大家需要注意的是如果我们传入的参数值有缺失会怎么呢?这个时候拼接的sql语句就会变得有问题,例如不传参数或者丢失最后一个参数,那么语句中就会多一个where或者and的关键字,因此在mybatis中也给出了具体的解决方案:
where
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
现在看起来没有什么问题了,但是我们的条件添加到了拼接sql语句的前后,那么我们该如何处理呢?
trim
foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。
choose、when、otherwise
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
set
用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
bind
bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:
sql
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。比如:
这个 SQL 片段可以在其它语句中使用,例如:
MyBatis常用OGNL表达式
缓存
MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。
默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
当添加上该标签之后,会有如下效果:
- 映射语句文件中的所有 select 语句的结果将会被缓存。
- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
- 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
- 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
- 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
在进行配置的时候还会分为一级缓存和二级缓存:
一级缓存:线程级别的缓存,是本地缓存,sqlSession级别的缓存
二级缓存:全局范围的缓存,不止局限于当前会话
一级缓存的使用
一级缓存是sqlsession级别的缓存,默认是存在的。在下面的案例中,大家发现我发送了两个相同的请求,但是sql语句仅仅执行了一次,那么就意味着第一次查询的时候已经将结果进行了缓存。
在大部分的情况下一级缓存是可以的,但是有几种特殊的情况会造成一级缓存失效:
- 一级缓存是sqlSession级别的缓存,如果在应用程序中只有开启了多个sqlsession,那么会造成缓存失效
2、在编写查询的sql语句的时候,一定要注意传递的参数,如果参数不一致,那么也不会缓存结果
3、如果在发送过程中发生了数据的修改,那么结果就不会缓存
4、在两次查询期间,手动去清空缓存,也会让缓存失效
特性
二级缓存
二级缓存是全局作用域缓存,默认是不开启的,需要手动进行配置。
Mybatis提供二级缓存的接口以及实现,缓存实现的时候要求实体类实现Serializable接口,二级缓存在sqlSession关闭或提交之后才会生效。
缓存使用
- 配置文件
- 需要在使用二级缓存的映射文件出使用<cache/>标签标注
- 实体类必须要实现Serializable接口
缓存策略
eviction:表示缓存回收策略,默认是LRU
LRU:最近最少使用的,移除最长时间不被使用的对象
FIFO:先进先出,按照对象进入缓存的顺序来移除
SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象
flushInternal:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
size:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出
readonly:只读,true/false
true:只读缓存,会给所有调用这返回缓存对象的相同实例,因此这些对象不能被修改。
false:读写缓存,会返回缓存对象的拷贝(序列化实现),这种方式比较安全,默认值
缓存查询的顺序是先查询二级缓存再查询一级缓存
二级缓存的作用范围
如果设置了全局的二级缓存配置,那么在使用的时候需要注意,在每一个单独的select语句中,可以设置将查询缓存关闭,以完成特殊的设置
- 在setting中设置,是配置二级缓存开启,一级缓存默认一直开启
- select标签的useCache属性:
- 在每一个select的查询中可以设置当前查询是否要使用二级缓存,只对二级缓存有效
- sql标签的flushCache属性
- 增删改操作默认值为true,sql执行之后会清空一级缓存和二级缓存,而查询操作默认是false
- sqlSession.clearCache()
- 只是用来清楚一级缓存
特性
整合第三方缓存
- 整合redis
- 添加redis-mybatis 缓存适配器 依赖
b. 添加redis.properties在resources根目录
c. 设置mybatis二级缓存实现类
- 整合echcahe
- 导入对应的maven
- 导入echcahe配置文件
- mapper文件中添加自定义缓存
致谢:
有关Notion安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~
- 作者:卷神
- 链接:https://blog.952712.xyz/article/a459f695-da10-4c54-9305-b8be87efe792
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。




