mybatis有一个强大的特性,其他框架在拼接sql的时候要特别谨慎,比如哪里需要空格,还要注意去掉列表最后一个列名的逗号,mybtis的动态sql可以帮助我们逃离这样的痛苦挣扎,那就是动态SQL.它还可以处理一种情况,当你不确定你的参数不知道是不是为空的时候,我们不需要在业务逻辑中判断,直接在sql中处理,代码无比简洁。主要的动态sql标签如下:
(trim,set) (when, otherwise)
注意事项:
在mapper中如果出现大于号(>),小于号(),大于等于号(),小于等于号()等,最好需要转换成为实体符号,这是因为mapper是XML文件,xml文件本身就含有较多的<>这样的尖括号,所以解析的时候可能会解析出错。
原符号 | < | <= | > | >= | & | ' | " |
---|---|---|---|---|---|---|---|
替换符号 | < |
<= |
> |
>= |
& |
' |
" |
我们经常需要根据where后面的条件筛选出需要的数据,当多个条件拼接的时候,我们一般使用
当有两个查询条件的时候,sql语句是:select * from student where 1=1 and name like '%' ? '%' and age > ?
当有一个查询条件的时候:sql语句就变成:select * from student where 1=1 and name like '%' ? '%'
当没有查询条件的时候,sql语句是:
select * from student where 1=1
, ,
使用
如果where里面是不规范的,那我们可以通过
- prefix:在包含的内容前加上前缀,不是百分之百会加,会根据需要自动加
- suffix:在包含的内容后面加上后缀,不是百分之百会加,会根据需要自动加
- prefixOverrides:可以把包含内容的首部某些内容忽略(不能自己增加),不一定会忽略,根据需要自动忽略
- suffixOverrides:也可以把包含内容的尾部的某些内容忽略(不能自己增加),同上
下面这样的是错误的,当传入的name不为空,而且age大于0的时候
不会自己增加and在第二个age前面:
下面的是正确的,我们在两个
下面是后缀模式, prefix="set"
表示在整个语句前面加上前缀set, suffixoverride=","
表示每一个语句后面的后缀","可以被忽略,如果是需要的话。suffix=" where id = #{id}
表示在整个语句后面增加where id = #{id},:
update user
name=#{name} ,
age=#{age} ,
当然,我们对上面的语句还有动态解决的方案,那就是
update student
name=#{name},
age=#{age},
score=#{score},
where id=#{id}
, ,
有时候,我们只想去匹配第一个条件,或者第一个条件不匹配的时候才会去匹配第二个条件,不像
foreach
动态SQL要有一个比较多的操作是对一个集合进行遍历,通常是在构建IN条件语句的时候。需要注意的点:
- collection 表示需要遍历的集合类型,array表示需要遍历的数组
- open,close,separator是对遍历内容的SQL拼接
- foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及在迭代结果之间放置分隔符。
- 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
1.比如我们需要查找学生的id为1,2,3的学生信息,我们不希望分开一次査一个,而是希望将数组id一次传进去,查出来一个学生的集合。
sql接口可以这样写,传入一个对象的数组:
public ListselectStudentByDynamicSQLForeachArray(Object[]studentIds);
sql语句如下,遍历array数组的时候,指定左边符号是左括号,右边是右括号,元素以逗号分隔开:
2.当遍历的是一个类型为int的list列表时:
public ListselectStudentByDynamicSQLForeachList(ListstudentIds);
sql语句如下,colleaction指定为list:
3.当遍历的是一个类型为对象的list:
public ListselectStudentByDynamicSQLForeachListStudent(Liststudents);
sql语句里面与上面相似,只是在使用属性的时候不太一样:
用于定义sql片段,方便在其他SQL标签里面复用,在其他地方复用的时候需要使用
select id,name,age,score
from student
动态sql让SQL写起来更加简洁,减少了很多重复代码,动态sql之间可以相互拼接,只要符合sql语句规范即可。
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。