動態 SQLjava
動態 SQL 是mybatis一個很強大的特性,咱們常常會由於不一樣的條件去拼接sql,一不當心可能就會少了個空格,或是列名後面多了個逗號。利用動態sql能夠很靈活的去爲咱們拼接sql,且相對簡潔清晰。sql
這裏咱們主要來了解下面幾個元素:數組
咱們先看一下語法mybatis
<select id="selectUser" resultMap="upmsUser"> select * from upms_user where is_locked = 1 <if test="loginname != null"> and loginname like #{loginname} </if> </select>
test 裏面是對條件的判斷,若裏面爲 true 的話,便會加上 if 元素裏的內容。如上面的loginname不爲空的話,sql語句就會是
select * from upms_user where is_locked = 1 and loginname like #{loginname}
ide
test 裏面的 與 和 或 不能用
&&
和||
,而是要使用and
和or
codetest 屬性值是不能包含 '<' 字符的, 因此判斷大小不能用
<
和<=
,用lt
和lte
代替。>
和>=
雖然能夠用,但規範起見,最好也用gt
和gte
代替xml
<select id="selectUser" resultMap="upmsUser"> select * from upms_user where is_locked = 1 <if test="upmsUser.age gte 10 and upmsUser.age lt 20"> <if test="loginname != null and loginname != '' "> and loginname like #{loginname} </if> </if> </select>
有時候咱們只想應用多個條件語句中的一個,咱們就要用到 choose (when, otherwise)
了。它與 java 中的 if...else if...else
和 switch
很像。對象
<select id="selectUser" resultMap="upmsUser"> select * from upms_user where is_locked = 1 <choose> <when test="loginname != null and loginname != '' "> and loginname like #{loginname} </when> <when test="upmsUser != null and upmsUser.realname != '' "> and realname like #{upmsUser.realname} </when> <otherwise> and phone is not null </otherwise> </choose> </select>
test屬性值的語法和 if 元素的是同樣的索引
這裏咱們先回到 if 的第一個例子,假如把 is_locked 字段也設爲動態的字符串
<select id="selectUser" resultMap="upmsUser"> select * from upms_user where <if test="locked != null"> is_locked = #{locked} </if> <if test="loginname != null and loginname != '' "> and loginname like #{loginname} </if> </select>
若是兩個 if 的條件都成立,這時是沒有問題的,但有兩個狀況下會出問題。
select * from upms_user where
(多了一個where)select * from upms_user where and loginname like #{loginname}
(多了一個and)這裏其實咱們能夠在 where 後面加上一個 1=1
,但 mabatis 給了咱們一個更好的解決方法
<select id="selectUser" resultMap="upmsUser"> select * from upms_user <where> <if test="locked != null"> is_locked = #{locked} </if> <if test="loginname != null and loginname != '' "> and loginname like #{loginname} </if> </where> </select>
使用 where 元素,它會在沒有條件成立時去掉where
,在有條件成立的時候檢查語句的開頭,並去掉多餘的 and
或是 or
一樣的道理,咱們在更新數據時使用 if 動態更新語句也可能會出現問題。這裏能夠使用 set 元素
<update id="updateUser"> update user <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="phone != null">phone=#{phone}</if> </set> where id=#{id} </update>
它會刪除set語句後面可能會多出來的逗號
有時候咱們在其餘地方可能也須要相似的功能,去除某些語句開頭或結尾多出來的符號或是鏈接詞。這時候咱們能夠使用 trim 去定製某些功能
<!-- prefix:前綴詞 prefixOverrides:語句前多餘要去除的內容 suffixOverrides:語句後多餘要去除的內容 --> <trim prefix="" prefixOverrides="" suffixOverrides=""> ... </trim>
這裏咱們能夠自定義與 where 和 set 元素等價的 trim 元素
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim> <trim prefix="SET" suffixOverrides=","> ... </trim>
動態 SQL 的另一個經常使用的操做需求是對一個集合進行遍歷,一般是在構建 IN 條件語句的時候
<select id="selectUser" resultMap="upmsUser"> select * from upms_user where user_id in <foreach item="item" index="index" collection="userIdList" open="(" separator="," close=")"> #{item} </foreach> </select>
collection 表示要遍歷的集合或數組,item 表示當前遍歷的對象,index 表示當前遍歷的序號或鍵,在元素體內使用的集合項(item)和索引(index)變量。
open、close、separator 能夠指定開頭與結尾的字符串以及在迭代結果之間放置分隔符
你能夠將任何可迭代對象(如 List、Set 等)、Map 對象或者數組對象傳遞給 foreach 做爲集合參數。當使用可迭代對象或者數組時,index 是當前迭代的次數,item 的值是本次迭代獲取的元素。當使用 Map 對象(或者 Map.Entry 對象的集合)時,index 是鍵,item 是值
bind 元素能夠從 OGNL 表達式中建立一個變量並將其綁定到上下文
<select id="selectUser" resultMap="User"> <bind name="pattern" value="'%' + user.getLoginname() + '%'" /> SELECT * FROM upms_user WHERE loginname LIKE #{pattern} </select>