【Java EE】動態SQL

動態SQL

概述

MyBatis的動態SQL包括以下幾種元素:

元素 作用 備註
if 判斷語句 單條件分支判斷
choose(when, otherwise) 相當於Java種的switch和case語句 多條件分支判斷
trim(where, set) 輔助元素,用於處理特定的SQL拼裝問題,比如去掉多餘的and、or等 用戶處理SQL拼裝的問題
foreach 循環語句 在in語句等列舉條件常用

if元素

if元素是最常用的判斷語句,它常常與test屬性聯合使用。使用if構建動態SQL語句如下:

<select id="findRole" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role where 1=1
	<if test="roleName!=null and roleName!=''">
		and role_name like concat('%',#{roleName},'%')
	</if>
</select>

choose、when、otherwise元素

在映射器的動態語句種choose、when、otherwise這三個元素承擔了多種選擇的功能。示例如下:

<select id="findRole" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role 
	where 1=1
	<choose>
	<when test="roleNo!=null and roleNo!=''">
		AND role_no = #{roleNo}
	</when>
	<when test="roleName!=null and roleName !=''">
		AND role_name like concat('%', #{roleName},'%')
	</when>
	<otherwise>
		AND note is not null
	</otherwise>
	</choose>
</select>

trim、where、set元素

加入條件“1=1”是顯得很奇快,可以用where元素去處理SQL以達到預期效果。示例如下:

<select id="findRole" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role 
	<where>
	<if test="roleName!=null and roleName!=''">
		AND role_name like concat('%', #{roleName},'%')
	</if>
	<if test="roleName!=null and roleName !=''">
		AND note like concat('%', #{note},'%')
	</if>
	</where>
</select>

當where元素裏面的條件成立,纔會加入where這個SQL關鍵字到組裝的SQL裏面,否則就不加入。
trim元素可以去掉一些特殊的SQL語法,比如常見的and、or等。示例如下:

<select id="findRoles" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role 
	<trim prefix="where" prefixOverride="and">
	<if test="roleName!=null and roleName!=''">
		AND role_name like concat('%', #{roleName},'%')
	</if>
	</trim>
</select>

trim元素意味着要去掉一些特殊的字符串,當prefix代表的是語句的前綴,而prefixOverride代表的是需要去掉哪種字符串。
在MyBatis種,常常可以使用set元素避免發送所有的字段給持久對象。示例如下:

<update id="updateRole" parameterType="role">
	update t_role
	<set>
		<if test="roleName != null and roleName != ''">
			role_name = #{roleName}
		</if>
		<if test = "note != null and note != ''">
			note = #{note}
		</if>
	</set>
</update>

set元素遇到了逗號,它會把對應的逗號去掉。

foreach元素

foreach元素是一個循環語句,他的作用是遍歷集合,它能夠很好地支持數組和List、Set接口的集合,對此提供遍歷功能。它往往用於SQL中的in關鍵字。示例如下:

<select id ="findUserBySex" resultType="user">
select * from t_role where role_no in 
	<foreach item = "roleNo" index="index" collection="roleNoList" open="("separator="," close=)">
	#{roleNo}
	</foreach>
</select>

其中:

  • collection配置的roleNoList是傳遞進來的參數名,可以是一個數組、List、Set等集合
  • item配置的是循環中當前的元素
  • index配置的是當前元素在集合的位置下標
  • open和close配置的是以什麼符號將這些集合元素包裝起來
  • separator是各個元素的間隔符

用test的屬性判斷字符串

test用於條件判斷語句,在MyBatis中使用廣泛。示例如下:

<select id="getRoleTest" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role
	<if test="type == 'Y'.toString()">
		where 1=1
	</if>
</select>

如果把type='Y’傳遞給SQL,就可以發現MyBatis加入了條件where 1=1。

bind元素

bind元素的作用是通過OGNL表達式去自定義一個上下文變量,在進行模糊查詢時,如果是MySQL數據庫,常常用到的是一個concat,它用"%"和參數相連,如果是Oracle,則用連接符號“||”,這樣需要提供兩種形式,有了bind元素,就不必使用數據庫語言,而是使用MyBatis的動態SQL即可完成。示例如下:

<select id="findRole" parameterType="string" resultMap="com.learn.ssm.mybatis.bean.RoleBean">
	<bind name="pattern" value = "'%'+_parameter+'%'"/>
	select id, role_name as roleName, create_date as createDate, end_date as endDate, end_flag as endFlag, note 
	from t_role where role_name like #{pattern}
</select>

這裏的“_parameter”代表傳遞進來的參數,它和通配符(%)連接後賦給了pattern,然後就可以在select語句中使用這個變量進行模糊查詢了。
MyBatis支持多個參數值使用bind元素的用法,傳遞多個參數前,首先定義接口方法:

public List<RoleBean> findRole(@Param("roleName") String roleName, @Param("note") String note);

定義映射文件和兩個新的變量,然後執行模糊查詢,如下所示:

<select id="findRole" resultMap="com.learn.ssm.mybatis.bean.RoleBean">
	<bind name="pattern_roleName" value = "'%'+_roleName+'%'"/>
	<bind name="pattern_note" value="'%'+ note + '%'"/>
	select id, role_name as roleName, create_date as createDate, end_date as endDate, end_flag as endFlag, note 
	from t_role where role_name like #{pattern_roleName} and note like #{pattern_note}
</select>

這裏綁定了兩個新的變量pattern_roleName和pattern_note,這樣就可以在SQL的其他地方使用了。

發佈了245 篇原創文章 · 獲贊 140 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章