MyBatis學習(五):動態SQL

關於動態SQL使用時的傳參方式
一般情況下映射文件中不寫參數,即省略parameterType項,在傳參時,將參數名和參數值put入Map對象中,傳遞Map類對象。在映射文件中直接#{參數名}使用。

if標籤用於無條件查詢或者單條件查詢
可以用與多條件查詢,但是需要把控傳入的參數不會造成SQL語句的錯誤
<if></if>標籤中的test表示if成立的條件,test=“”引號內爲判斷條件,如果成立,直接將if標籤內的SQL拼接在前面的SQL語句之後。

基本格式:

			<!-- 通過Map傳參,Map中是否含有name鍵 -->
	        <if test="name!=null">
    			where p.name like concat('%',#{name},'%')
    		</if>
    		<!--可以使用多個if語句-->
    		<if test="id!=null">
    			where p.id = #{id}
    		</if>

where標籤 用於無條件查詢或者多條件查詢
where標籤的作用:

  • 起where關鍵字的作用
  • 可以自動去掉SQL語句中不符合SQL語法規則的and、or等連接符

<where></where>標籤和標籤一起使用,其基本格式如下:

當where標籤內的if標籤成立時,會將if標籤內的語句連接在SQL語句的後面,如果if標籤的語句含有無用的and或者or,則自動刪去

			<where>
  				<if test="id!=null">
  					and p.id=#{id}
  				</if>
  				<if test="name!=null">
  					and p.name like concat("%",#{name},"%")
  				</if>
  			</where>

set標籤用於數據更新時選擇條件更新
set標籤的作用(和where標籤的作用類似,內部使用if標籤):

  • 起set關鍵字的作用
  • 自動添加逗號

基本格式如下:

    <set>
     	<if test="name != null">name=#{name},</if>
     	<if test="price != null">price=#{price}</if>
    </set>

trim標籤:字符串的處理,包括拼接字符和去除字符,可以從首部或者尾部

prefix:給sql語句拼接的前綴
suffix:給sql語句拼接的後綴
prefixesToOverride: 去除sql語句前面的關鍵字或者字符,該關鍵字或者字符由prefixesToOverride屬性指定,假設該屬性指定爲”AND”,當sql語句的開頭爲”AND”,trim標籤將會去除該”AND”
suffixesToOverride: 去除sql語句後面的關鍵字或者字符,該關鍵字或者字符由suffixesToOverride屬性指定

實現where標籤功能:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>

實現set標籤功能:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

choose標籤:用於選擇條件查詢,或者條件存在互斥
<choose></choose>標籤同樣和<where>標籤一起使用
<choose>標籤作爲<if><\if>標籤的補充,相當於if else的功能,<when></when>標籤相當於if,<otherwise></otherwise>標籤相當於else ,當所有的when條件都不成立時,choose標籤纔會執行;如果有一個成立,choose標籤語句都不會執行。
當有多個<when></when>標籤時,相當於if ,else if, else;只會執行條件最先成立的那一個。choose:選擇,選擇一個標籤執行內的語句執行
基本結構如下:

   		<where>
    			<choose>
    				<when test="price!=null">
    					price > #{price}
    				</when>
    				<when test="name!=null">
    					p.name like concat("%",#{name},"%")
    				</when>
    				<otherwise>
    					p.id = 6
    				</otherwise>
    			</choose>
    		</where>

foreach標籤用於多值查詢(in)
foreach標籤就是用於在使用in進行條件查詢時,用於構建in後的內容
foreach標籤內含有如下元素:
collection :collection屬性的值有三個分別是list、array、map三種,分別對應的參數類型爲:List、數組、map集合
item : 表示在迭代過程中每一個元素的別名
index :在list和數組中,index是元素的序號,在map中,index是元素的key,該參數可選。
open :前綴
close :後綴
separator :分隔符,表示迭代時每個元素之間以什麼分隔

關於collection參數的問題:
foreach 迭代對象必須是實現 Iterator 接口或者是Map類型的對象。

  • 如果在JAVA代碼中直接傳入List或者數組,直接使用list、array(使用傳入的參數名會報錯);
  • 如果傳入的參數爲map類型或者對象類型,參數應該爲屬性值。比如傳入一個Map類型的對象(對象由HashMap類實例化),collection=“key值”,並且要保證key所對應的value值可以使用Iterator進行迭代。如下所示:
	List<Integer> paramesList=new ArrayList<>();
	paramesList.add(1);
	paramesList.add(2);
	paramesList.add(3);
	int[] paramesArray= {1,2,3};
	Map<String,Object> paramesMap=new HashMap<>();
	paramesMap.put("value1", 1);
	paramesMap.put("value2", paramesList);
	paramesMap.put("value3",paramesArray);
//	List<Product> ps=session.selectList("selectProductForeach", parames);
//	List<Product> ps=session.selectList("selectProductForeach", paramesArray);
	List<Product> ps=session.selectList("selectProductForeach", paramesMap);
//	List<Product> ps=session.selectList("selectProductForeach", c);
	for(Product p:ps)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}
	session.close();
    	<!-- foreach 標籤的使用  -->
    	<select id="selectProductForeach" resultType="Product">
    		select * from product where id in 
    		<foreach collection="value3" item="item" index="index" open="(" separator="," close=")">
    			#{item}
    		</foreach>
    	</select>

使用value3或者value4時,均可以正常執行。使用value1會產生**Error evaluating expression ‘value1’. Return value (1) was not iterable.**錯誤。

如果是使用封裝的對象,對象含有List集合屬性,可以使用如下操作:

/*
public class Category {
	private int id;
	private String name;
	List<Product> products;
}
public class Product {
	private int id;
	private String name;
	private float price;
	private Category category;
}
*/
Category c=session.selectOne("selectCategoryByID",1);
List<Product> ps=session.selectList("selectProductForeach", c);
	<!-- foreach 標籤的使用  -->
    	<select id="selectProductForeach" resultType="Product">
    		select * from product where id in 
    		<foreach collection="products" item="item" index="index" open="(" separator="," close=")">
    			#{item.id}
    		</foreach>
    	</select>

bind標籤:實現一次字符串的拼接,在本地以字符串加減的形式實現,避免了使用數據庫的concat函數
普通模糊查詢和使用bind

 	<!-- -bind標籤學習 -->
    	<select id="selectProductByNameNB" resultType="Product">
    		select * from product where name like concat("%",#{name},"%")
    	</select>
     	<select id="selectProductByNameBind" resultType="Product">
    		<bind name="likename" value="'%'+name+'%'"/>
    		select * from product where name like #{likename}
    	</select> 

注意value裏字符串拼接的方式,字符使用單引號括起來,變量直接+;但是這樣也產生了一個問題:
java代碼:

	/**************bind標籤學習*************/
	List<Product> ps=session.selectList("selectProductByNameNB", "product1");
	for(Product p:ps)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}
	System.out.println("--------------");
	List<Product> ps2=session.selectList("selectProductByNameBind", "product1");
	for(Product p:ps2)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}

運行結果:
在這裏插入圖片描述
查詢時都是傳入直接傳入字符串參數,select標籤中都是省略了parameterType選項,但是普通模糊查詢正確運行,使用bind標籤卻找不到name的值,此處需要使用Map傳值纔可以,如下:

	Map<String,Object> param=new HashMap<>();
	param.put("name", "product1");
	List<Product> ps2=session.selectList("selectProductByNameBind", param);
	for(Product p:ps2)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章