動態SQL語句,也就意味着SQL語句不在是一成不變的而是具有多樣性.
if
if的用法還是跟平常差不多的(不過沒有else if也沒有else)
<update id="modify" parameterType="User"> UPDATE `smbms_user` <trim prefix="set" suffixOverrides="," suffix="where id=#{id}"> <if test="userCode!=null">`userCode` = #{userCode} , </if> <if test="userName!=null">`userName` = #{userName} , </if> <if test="userPassword!=null">`userPassword` = #{userPassword} , </if> <if test="gender!=null">`gender` = #{gender} , </if> <if test="birthday!=null">`birthday` = #{birthday} ,</if> <if test="phone!=null">`phone` = #{phone} , </if> <if test="address!=null">`address` = #{address} , </if> <if test="userRole!=null">`userRole` = #{userRole} , </if> <if test="createdBy!=null">`createdBy` = #{createdBy} , </if> <if test="creationDate!=null">`creationDate` = #{creationDate} , </if> <if test="modifyBy!=null">`modifyBy` = #{modifyBy}</if> </trim> </update>
如上面的代碼,如果是空的字段則不執行更新操作
choose(when,otherwise)
choose就相當於Java中的switch,when相當於case,otherwise相當於default
<select id="getBill" resultType="Bill"> SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id WHERE 1=1 <choose> <!-- 條件為false則繼續執行下面的when,反之亦然如此 --> <when test="id!=null"> AND b.providerId=#{id} </when> <!-- 條件為true則不會執行otherwise,反之亦然如此 --> <when test="proName!=null"> AND p.proName LIKE CONCAT('%',#{proName},'%') </when> <!-- 當都不滿足時執行默認值 --> <otherwise> AND p.proContact LIKE CONCAT('%張%') </otherwise> </choose> </select>
where
此標簽可以忽略條件中多余的and和or如下
SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id <where> <if test="id!=null"> AND b.providerId=#{id} </if> <if test="proName!=null"> AND p.proName LIKE CONCAT('%',#{proName},'%') </if> </where>
假設id為1 proName為北京 兩個if都滿足條件時就會拼湊成這樣
SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id WHERE b.providerId=1 AND p.proName LIKE CONCAT('%北京%')
其實解決這種情況不用where也是可以的,只需在前面加上一個為真的條件即可
SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id where 1=1 <if test="id!=null"> AND b.providerId=#{id} </if> <if test="proName!=null"> AND p.proName LIKE CONCAT('%',#{proName},'%') </if>
效果也是一樣的
set
此標簽可以忽略多余的逗號
UPDATE `smbms_user` <set> <if test="userPassword!=null"> `userPassword` = #{userPassword}, </if> </set> WHERE `id` = #{id} ;
trim
此標簽屬性如下
- prefix:通過自動識別是否有返回值,在trim包含的內容上加上前綴
- suffix:在trim包含的內容上加上后綴
- prefixoverrides:對trim包含內容的首部進行指定內容的忽略
- suffixoverrides;對於trim包含內容的尾部進行指定內容的忽略
栗子1
<!-- 添加內容前面加上 where 並且忽略 and或者or --> <trim prefix="where" prefixOverrides="and|or"> <if test="userRole!=null"> and userRole=#{userRole} </if> <if test="userName!=null and userName!=''"> and u.userName like CONCAT('%',#{userName},'%') </if> order by creationDate DESC limit #(from),#(pageSize) </trim>
栗子2
UPDATE `smbms_user` <!-- 在內容前加上 set 並且忽略內容最后的逗號 且在內容后面加上查詢條件 --> <trim prefix="set" suffixOverrides="," suffix="where id=#{id}"> <if test="userCode!=null">`userCode` = #{userCode} , </if> <if test="userName!=null">`userName` = #{userName} , </if> </trim>
foreach
此標簽的屬性如下
- item表示集合中每一個元素進行迭代時的別名
- index:指定一個名字,用於表示每次迭代的位置.好比for循環中自定義的 i
- open表示該語句以什么開始,在in條件語句中以"("開始
- separator表示在每次進行迭代之間以什么符號作為分隔 符,在in條件語句中以逗號進行分隔
- close表示以什么結束。在in條件語句中以")"結尾
- 在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,主要有以下3種情況:
- 如果傳入的是單參數且參數類型是一個List的時候,collection屬性值為list
- 如果傳入的是單參數且參數類型是一個array數組的時候,collection的屬性值為array
- 如果傳入的參數是多個的時候,我們一般把它們封裝成一個Map了,此時屬性值為map其中的一個key
栗子1
當入參為list時
<select id="getUSerByRoleId_foreach_list" resultMap="userMapByRole"> select * from smbms_user where userRole in <!-- 因為此處用了in,因此以 "("開頭 ,")"結尾 ,","分隔 --> <foreach collection="list" item="roleList" open="(" separator="," close=")"> #{roleList} </foreach> </select>
栗子2
當入參為數組時
<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole"> select * from smbms_user where userRole in <!-- 因為此處用了in,因此以 "("開頭 ,")"結尾 ,用","分隔 --> <foreach collection="array" item="roleIds" open="(" separator="," close=")"> #{roleIds} </foreach> </select>
栗子3
當為map時
<select id="getProvider" resultMap="providerresult"> SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id where b.providerId in <!-- 因為此處用了in,因此以 "("開頭 ,")"結尾 ,","分隔 此時的collection的值是map其中的一個key--> <foreach collection="#{bibli}" item="pros" open="(" separator="," close=")"> <!-- 獲取對象當中的屬性 --> #{pros.providerId} </foreach> </select>
小結
- if+set:動態完成更新操作
- if+where:動態完成多條件查詢
- if+trim:完成多條件查詢(代替where)或者更新操作(代替set)
- choose(when,otherwise):動態完成多條件查詢(多選一)
- foreach:主要用於in條件查詢中,迭代集合,最關鍵的部分為collection屬性,根據不同的入參類型,該屬性值則不同
-
- 如果傳入的是單參數且參數類型是一個List的時候,collection屬性值為list
- 如果傳入的是單參數且參數類型是一個array數組的時候,collection的屬性值為array
- 如果傳入的參數是多個的時候,我們一般把它們封裝成一個Map了,此時屬性值為map其中的一個key
