MyBatis學習_3_動態SQL

<if>元素

<if>元素是簡單的條件判斷,可用來實現某些簡單的條件選擇,書上舉的例子是:當輸入查詢條件是,按條件模糊查詢用戶名,當什麼都沒輸入時,查詢所有用戶名。我先說步驟,再說我的看法吧。
1.在UsrInfoMapper.xml映射文件中配置select語句塊

<!--動態SQL之<if>元素  -->
 	<select id="findUserInfoUserNameWithIf" parameterType="userInfo" resultType="UserInfo">
 		select * from user_info ui 
 		<if test="userName!=null and userName!=''">
 			where ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 		</if>
 	</select>

2.創建接口並聲明方法

package com.mybatis.mapper;

import java.util.List;

import com.mybatis.pojo.UserInfo;

public interface UserInfoMapper {
	List<UserInfo> findUserInfoUserNameWithIf(UserInfo ui);
}

3.寫測試方法

@Test
	public void testFindUserInfoUserNameWithIf() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		UserInfo ui = new UserInfo();
		ui.setUserName("j");//後面註釋掉這行做測試
		List<UserInfo> list = uim.findUserInfoUserNameWithIf(ui);
		for (UserInfo uInfo : list) {
			System.out.println(uInfo.toString());
		}
	}

4.先測試正常設置了查詢值的時候
在這裏插入圖片描述
再測試沒有設置查詢值的情況,也就是註釋掉那行代碼做測試
在這裏插入圖片描述
發現sql語句少了where的部分,查詢的是全部用戶
我是這麼想的,在接受到表單數據時,加個if判斷他不香嗎?還能多寫幾種條件。

<where> <if>元素

當<if>元素較多時,可能會拼裝成 where and 或者 where or 之類的關鍵字多餘的錯誤SQL語句,這時候就應該用到<where>元素。
1.在UsrInfoMapper.xml映射文件中配置select語句塊

<!--動態SQL之<where>元素  -->
 	<select id="findUserInfoByUserNameAndStatus" parameterType="UserInfo" resultType="UserInfo">
 		select * from user_info ui
 		<where>
 			<if test="userName!=null and userName!=''">
 			 ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 			</if>
 			<if test="status>-1">
 				and ui.status = #{status}
 			</if>
 		</where>
 	</select>

2.創建接口並聲明方法
在這裏插入圖片描述
3.寫測試方法,主要測試以下幾種情況
都輸入了值時
在這裏插入圖片描述
當設置status值爲-1時
在這裏插入圖片描述
當沒有輸入姓名查詢條件時
在這裏插入圖片描述

<set> <if>元素

<set> 和 <if>元素可用來組裝update語句,只有當<set>元素內的條件成立時,纔會在組裝SQL語句時加上set關鍵字.<set>元素內包含了<if>子元素,每個<if>元素包含的SQL後面會有一個逗號,拼接好的SQL語句中會包含多餘的逗號,從而造成SQL語法錯誤,不過<set>元素能將SQL語句中的多餘逗號剔除。

<!--動態SQL之<set><if>元素  -->
 	<update id="updateUserInfo" parameterType="UserInfo">
 		update user_info ui
 		<set>
 			<if test="userName!=null and userName!=''">
 				ui.userName = #{userName},
 			</if>
 			<if test="password!=null and password!=''">
 				ui.password = #{password}
 			</if>
 		</set>
 		where ui.id=#{id}
 	</update>

在這裏插入圖片描述

@Test
	public void testUpdateUserInfo() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		UserInfo ui = new UserInfo();
		ui.setId(3);
		//ui.setUserName("fzj");
		ui.setPassword("123");
		uim.updateUserInfo(ui);
	}

測試以下情形
都輸入了值
在這裏插入圖片描述
沒有輸用戶名
在這裏插入圖片描述
沒有輸密碼
在這裏插入圖片描述
id肯定要輸的,畢竟不再if裏,還是試一下
在這裏插入圖片描述
我以爲他會報錯,說少傳一個參數,但還是修改了,默認修改第0個,而表是從第一個開始,就相當於是沒修改。

<trim>元素

使用<trim>元素,可以通過prefix屬性在要拼裝的SQL語句片段前加上前綴,通過suffix屬性在要拼裝的SQL語句片段之後加上後綴,通過prefixOverrides屬性把要拼裝的SQL語句片段首部的某些內容覆蓋,通過suffixOverrides屬性把要拼裝的SQL語句片段尾部的某些內容覆蓋。因此<trim>元素可用來替代<where>元素和<set>元素實現同樣的功能。
使用<trim>元素替代<where>元素,從數據表user_info中按用戶名模糊查詢,同時查詢指定狀態的用戶列表,實現步驟如下所示。
1.編寫映射文件

<!--動態SQL之<trim>元素  -->
 	<select id="findUserInfoByUserNameWithIf_Trim" parameterType="UserInfo" resultType="UserInfo">
 		select * from user_info ui
 		<trim prefix="where" prefixOverrides="and|or">
 			<if test="userName!=null and userName!=''">
 				ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 			</if>
 			<if test="status>-1">
 				and ui.status = #{status}
 			</if>
 		</trim>
 	</select>

prefix屬性設置爲where,將要拼裝的SQL語句的前綴設置爲where,即要使用where關鍵字來連接後面的SQL語句片段;prefixOverrides屬性設置爲and|or,是將要拼裝的SQL語句片段首部多餘的“and”或“or”關鍵字去除
接口
在這裏插入圖片描述
測試方法

@Test
	public void testFindUserInfoByUserNameWithIf_Trim() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		UserInfo ui = new UserInfo();
		ui.setUserName("j");
		ui.setStatus(1);
		List<UserInfo> list = uim.findUserInfoByUserNameWithIf_Trim(ui);
		for (UserInfo userInfo : list) {
			System.out.println(userInfo.toString());
		}
	}

運行結果和where,if的一樣
在這裏插入圖片描述
接下來演示替代<set>

<!--動態SQL之<trim>元素<set>元素  -->
 	<update id="updateUserInfo_trim" parameterType="UserInfo">
 		update user_info ui
 		<trim prefix="set" suffixOverrides=",">
 			<if test="userName!=null and userName!=''">
 				ui.userName = #{userName},
 			</if>
 			<if test="password!=null and password!=''">
 				ui.password = #{password}
 			</if>
 		</trim>
 		where ui.id=#{id}
 	</update>

後續步驟省略。運行結果和<set>一樣

<choose>、<when>和<otherwise>元素

在查詢中,如果不想使用所有的條件,而只是想從多個選項中選擇一個,可以使用MyBatis提供的<choose>、<when>和<otherwise>元素來實現。<choose>元素會按順序判斷<when>元素中的條件是否成立,如果有一個成立,則不再判斷後面<when>元素中的條件是否成立,<choose>元素執行結束;如果所有<when>的條件都不滿足,則執行<otherwise>元素中的SQL語句。
如果想從數據表user_info中根據userName或status進行查詢,當userName不爲空時則只按照userName查詢,其他條件忽略;否則當status大於-1時,則只按照status查詢;當userName和status都爲空時,則查詢所有用戶記錄,使用<choose>、<when>和<otherwise>元素實現這個示例的步驟如下所示。

<!--動態SQL之<choose><when><otherwise>元素  -->
 	<select id="findUserInfo_Choose" parameterType="UserInfo" resultType="UserInfo">
 		select * from user_info ui
 		<where>
 			<choose>
 				<when test="userName!=null and userName!=''">
 					ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 				</when>
 				<when test="status>-1">
 					and ui.status = #{status}
 				</when>
 				<otherwise>
 				</otherwise>
 			</choose>
 		</where>
 	</select>

後續流程還是上面那一套,運行結果也一樣,畢竟是替代嘛。

<foreach>元素

<foreach>元素主要是迭代一個集合,通常是用於in條件。例如SQL中的條件形如:where id in(一大串的id),這時可使用<foreach>元素,而不必去拼接id字符串。
<foreach>元素可以向SQL語句傳遞數組、List<E>等實例。List<E>實例使用list做爲鍵,數組實例使用array做爲鍵。
如果想從數據表user_info中查詢id爲1和3的用戶記錄,使用<foreach>元素的List實例的實現步驟如下所示。

<!--動態SQL之<foreach>元素,使用List<E>實例  -->
 	<select id="findUserInfoByIds" resultType="UserInfo">
 		select * from user_info ui where ui.id in
 		<foreach collection="list" item="ids" open="(" close=")" separator=",">
 			#{ids}
 		</foreach>
 	</select>

有以下幾點要說明
item屬性表示集合中每個元素迭代時的別名
open表示該語句的開始符號,separator表示每次迭代之間的分隔符號,close表示該語句結束符號
collections屬性根據具體情況選擇list或array

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
上面這個是<foreach>的List<E>實例的實現步驟
下面試一下arrea實例的實現

<!--動態SQL之<foreach>元素,使用array實例  -->
 	<select id="findUserInfoByIds2" resultType="UserInfo">
 		select * from user_info ui where ui.id in
 		<foreach collection="array" item="ids" open="(" close=")" separator=",">
 			#{ids}
 		</foreach>
 	</select>

在這裏插入圖片描述

@Test
	public void testFindUserInfoByIds2() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		//創建集合對象ids,保存用戶id
		int[] ids = new int[2];
		ids[0]=1;
		ids[1]=2;
		List<UserInfo> userInfos=uim.findUserInfoByIds2(ids);
		for (UserInfo userInfo : userInfos) {
			System.out.println(userInfo.toString());
		}
	}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章