動態SQL其實就是根據不同的條件生成不同的SQL,MyBatis中有where、if、choose、when、otherwise、set、foreach等標簽,我們可以使用這些標簽來對參數值進行條件判斷,進而拼接成不同的SQL。中文文檔 https://mybatis.org/mybatis-3/zh/dynamic-sql.html
示例中使用的實體類
// 省略了get、set、構造器等方法
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
1. where和if標簽
where標簽和if標簽都可以單獨使用,我這里為了方便演示,在示例中就放在一起了。
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from blog
<!-- where標簽會自動添加where語句,並將后面滿足條件的if標簽中的內容進行拼接,
並且如果拼接之后檢查到where之后緊接着的開始語句是and或or的的話,也會自動刪除單詞and或or,
當然如果所有if都不滿足,where語句也不會拼接到SQL里。
例如:如果下面第一個if沒有滿足,第二if滿足了,直接拼接的話就會變成where and,這樣的SQL是有問題的,
所以where標簽會自動將這個and給刪除掉 ,當然如果兩個條件都不滿足,
where語句也不會拼接到最終的SQL里 -->
<where>
<!-- test中是對傳入參數的判斷,這里的title != null表示是map中有key為title且不為null時才滿足條件,
通常沒有傳入該參數的話就會是null -->
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
2. choose,when和otherwise標簽
choose,when和otherwise標簽類似於java的switch,case和default語句。
<select id="queryBlogWhen" parameterType="map" resultType="Blog">
select * from blog
<where>
<!-- choose標簽類似於java中的switch case語句,從上往下順序判斷,
只要遇到滿足條件的when標簽,就會拼接對應的SQL,其他的when標簽就不會再去判斷了,
如果所有when標簽都不滿足的話,則會拼接最后的otherwise標簽的SQL -->
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
3. set標簽
set標簽用於拼接update更新操作的SQL,注意示例中使用的標簽是update,不再是select查詢標簽了。
<update id="updateBlogSet" parameterType="map">
update blog
<!-- set標簽用於拼接update操作的set語句,會在之前的update語句之后自動添加set語句,
同時還會自動處理拼接后SQL中的逗號。例如:如果下面的if判斷只有第一個if滿足條件,
拼接之后在末尾就會多一個逗號,此時set標簽會自動刪除這個逗號,保證SQL語句的合法性 -->
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
<!-- 這里的where語句也可以使用where標簽進行更復雜的查詢 -->
where id = #{id}
</update>
4. foreach標簽
foreach標簽用於在參數是集合類型的場景下,我們可以循環遍歷集合中的元素並拼接到SQL中。
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from blog where id in
<!-- foreach標簽會根據指定規則拼接SQL,比如下面的配置:collection="ids"表示
從參數map中根據key="ids"拿到對應的集合,然后遍歷集合中的元素,item="id"表示遍歷時元素對應的變量為id,
open="("表示拼接時開始的語句(可以是多個字符),open="("表示結束的語句(可以是多個字符),separator=","表示每個元素在拼接時使用的
連接符或分隔符(可以是多個字符),最終會生成的SQL為“ ( xxx , xxx , xxx ) ”,對應的空格(缺少的或多余的)會自動進行處理 -->
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
5. sql標簽
sql標簽用於提取公共的SQL配置,在需要使用的地方直接通過include標簽進行引用即可。
<!-- 可以使用sql標簽將常用的SQL抽取出來,在需要的地方使用include標簽進行引用即可 -->
<sql id="blogIf">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<select id="queryBlogIf2" parameterType="map" resultType="Blog">
select * from blog
<where>
<!-- 使用include標簽的refid引用對應的sql標簽內容 -->
<include refid="blogIf"/>
</where>
</select>