动态 SQL 概况
MyBatis 的强大特性之一便是它的动态 SQL
在 Java 开发中经常遇到条件判断, 比如:
- if(x>0){
- // 执行一些逻辑........
- }
Mybatis 应用中, SQL 映射通常位于 xml 文件内, 在执行前需要将 xml 中的映射转换为最终要执行的 SQL
在转换中是否可以根据输入动态的处理 SQL? 这就是动态 SQL, 比如
- <select id="findActiveBlogWithTitleLike" resultType="Blog">
- SELECT * FROM BLOG WHERE state = 'ACTIVE'
- <if test="title != null">
- AND title like #{title}
- </if>
- </select>
上面的 < if test="title != null"> 就是动态 SQL 处理, 将会根据实际传递的 title 的值, 动态的决定 SQL 的内容, 是否包含最后面的 AND
Mybatis 的动态 SQL 元素不多, 但是简单高效, Mybatis 的动态 SQL 元素类似 JSTL
类型主要有三种:
条件判断
内容处理
循环处理
对于每种不同的类型又有各自的格式和属性
条件处理
if 是最基本的一种形式, 语意为: 如果 xxx 就 xxx
通过最基本的 if 可以构造很复杂的条件测试语句, 相当于
if(){ }
choose 是特殊化的 if, 相当于
if(){ }else{ }
你可以添加多个 if, 比如
- if(){
- }if(){
- }if(){
- }else{
- }
通常对于一个 choose 是可以拆分为多个 if 条件的, 但是很显然, 某些场景下, 使用 if else 的形式比多个 if 要更加简单清晰
if 和 choose 里面 when 后的条件都是使用 test 进行设置的
内容处理
trim 用于动态内容头尾的处理, 可以添加前缀 prefix 或者添加后缀 suffix
也可以移除匹配的指定的前缀 prefixOverrides, 或者移除匹配的指定的后缀 suffixOverrides
简言之可以借助于 trim 对拼接内容的头尾进行处理
where 相当于
<trim prefix="WHERE" prefixOverrides="AND |OR">
表示在最前面添加 where, 如果最开始是 AND 或者 OR 将会进行删除
set 相当于 < trim prefix="SET" suffixOverrides=",">
表示在最前面添加 set, 如果最后面是一个逗号, 将他删除
循环遍历
foreach 用于动态的循环拼接, 相当于 for 循环动态拼接内容
- for(int i =0;i<list.size;i++){
- String s +="...";
- }
对于 foreach, 需要指明需要遍历循环的参数名称, 通过 collection 指定
需要指定循环变量, 也就是在循环中使用哪个变量指代, 相当于 Object o = list.get(i); 使用 item 指定的就是这个 o
还可以指定变量用于记录索引, 通过这个索引变量可以获得迭代的次数索引, 通过 index
对于 open, separator, close, 就是在字符串拼接的开头, 中间, 结尾, 添加的分割符信息.
总结
在实际项目应用中, 总是有很多的查询条件或者关联语句, 但是并不是每一次的查询都需要完整的语句, 难道每种场景都重新写一个 SQL 吗?
显然是效率低下的, Mybatis 的动态 SQL 就是解决这种问题的
动态 SQL 就是根据条件动态的处理 SQL 语句, 进而达到不同场景不同 SQL 的作用, 也就是写一次 SQL, 然后经过条件分支或者内容的处理, 能够在多个场景进行使用
从上面的介绍也可以看得出来, 动态 SQL 的本质在于根据条件, 对 SQL 语句处理, 可以理解为文本处理工作
他只是 Mybatis 一次执行时实际执行的 SQL 语句, 不管是 if 还是 choose 还是 where 还是 trim, 再或者是 foreach, 都是简单的对 SQL 进行拼接, 处理, 优化
对于程序员来说, 最重要的就是条件的判断, 也就是 test 后面的语句的书写, 再就是确认各种条件判断后处理后的 SQL 语句不会出现什么问题就够了
但是还需要注意, 尽管 Mybatis 有动态 SQL 功能, 可以灵活的拼接 SQL, 但是也不要滥用, 尽可能业务逻辑比较相似的, 通过条件进行控制
试想, 如果一整个表的所有逻辑全都是一个 SQL, 通过各种 if choose 拼接起来, 可读性是一个很大的问题, 所以也要合理
简单说几点就是:
动态 SQL 本质就是 SQL 语句的文本处理工作, 无他
要注意条件语句的设置
不要滥用动态 SQL, 该分开还是得分开
对于动态 SQL 根本仍旧是 SQL 的编写, 所以需要具有良好的 SQL 语句编写能力, 动态 SQL 只是可以让他更加灵活, 并不能解决你 SQL 中的任何问题, 或者性能问题
要始终记住, 他只是处理需要执行的 SQL
来源: https://www.cnblogs.com/noteless/p/10349745.html