在mybtis中動(dòng)態(tài)sql主要用到的幾個(gè)節(jié)點(diǎn)元素有:
1、if
2、choose(when, otherwise)
3、trim(where, if)
4、foreach
if的用法
- 用法: if的用法較為簡(jiǎn)單,對(duì)一些條件做出判斷,條件成立則執(zhí)行,不成立則跳過。
- 例子 當(dāng)我們數(shù)據(jù)字段較多時(shí),這是就會(huì)出現(xiàn)許多搜索條件,但在搜索時(shí)并不是所有的搜索條件,因此在寫sql語(yǔ)句時(shí)就需要我們判斷某些條件是否為空,如果為空就不執(zhí)行該字段的查詢。
<select id="queryStudentsByLikesAdmin" parameterType="map" resultType="map">
SELECT student.no,student.name,student.gender,direction.name direction,profession.name profession,classes.name
classesName
FROM t_student student
LEFT JOIN (SELECT id, name FROM t_direction) direction ON direction.id = student.direction_id
LEFT JOIN (SELECT id,name FROM t_profession) profession ON profession.id = student.profession_id
LEFT JOIN (SELECT id,name FROM t_classes) classes ON classes.id = student.classes_id
<where>
<if test="level!=''">
and student.level = ${level}
</if>
and student.no LIKE #{studentNo}
<if test="directionId!=''">
and direction_id =#{directionId}
</if>
<if test="professionId!=''">
AND profession.id = #{professionId}
</if>
<if test="classesId!=''">
AND student.classes_id = #{classesId}
</if>
and student.name
LIKE #{name}
</where>
</select>
choose(when, otherwise)的用法
- 用法:choose when 主要在多個(gè)條件的情況下只滿足其中一個(gè)條件的應(yīng)用場(chǎng)景中使用,例如這里就構(gòu)建一個(gè)query條件,分別傳遞id,name與createTime。假設(shè)我們查詢Visitor表時(shí),如果VisitorId有值則,使用Id查詢,如果VisitorName有值則采用VisitName查詢
- 例子:
<!-- 滿足其中一個(gè)條件時(shí)候用choose when操作 -->
<select id="getListChooseWhenDemo" resultMap="visitorRs"
parameterType="BasicQueryArgs">
<include refid="getListSqlConditions" />
<where>
<if test="queryStatus>0">
status=#{queryStatus}
</if>
<choose>
<when test="queryId!=0">
and id=#{queryId}
</when>
<when test="queryName!=null">
and name like #{queryName}
</when>
<otherwise>
and createTime>= #{queryTime}
</otherwise>
</choose>
</where>
</select>
- 在這里說一下<include>的用法,在mybatis中<sql>用來封裝SQL語(yǔ)句, <include>來調(diào)用。簡(jiǎn)單例子:
//<sql>封裝sql語(yǔ)句
<sql id="select">
select * from T_name
</sql>
<sql id="desc">
order by T_name.name DESC
</sql>
//<include>調(diào)用封裝好的sql語(yǔ)句
<select id="find" resultType="*">
<include refid="select" />
<include refid="desc" />
</select>
- 上面這段代碼的意思就是查詢T_name表中的全部信息,然后按照字段"name"進(jìn)行排序。
where if (trim)的用法
- where關(guān)鍵詞的好處是在于,如果有相應(yīng)的過濾條件的話,它知道在適當(dāng)?shù)臅r(shí)候插入where關(guān)鍵詞。而且它也知道在何時(shí)該去掉相應(yīng)的AND與OR的連接符
- 例子
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
不會(huì)因?yàn)樗袟l件不滿足變?yōu)?/p>
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE
</select>
或者因?yàn)闆]有滿足第一個(gè)條件,單單滿足后面的條件變成
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle'
</select>
- set trim和上面的where一樣,set和trim也是智能標(biāo)記
- 例子
<update id="updateUserSet" parameterType="User">
update User
<set>
<if test="userName != null">userName=#{userName},</if>
<if test="password != null">password=#{password},</if>
</set>
where id=#{id}
</update>
如果兩個(gè)條件都不為空,那么實(shí)際執(zhí)行的sql語(yǔ)句為:
update User SET userName=?, password=? where id=?
set 自動(dòng)識(shí)別并把sql語(yǔ)句中第二個(gè)逗號(hào)去掉的。
- trim標(biāo)識(shí)為格式化標(biāo)識(shí),可以與其他標(biāo)識(shí)完成where和set的功能
prefix 前綴增加 suffix 后綴增加 prefixOverrides 自動(dòng)判斷前置 suffixOverrides 自動(dòng)判斷后置
<update id="updateUserTrim" parameterType="User">
UPDATE User
<trim prefix="SET" suffixOverrides="," suffix="WHERE id = #{id}" >
<if test="userName != null and userName != '' ">
userName = #{userName},
</if>
<if test="password != null and password != '' ">
password=#{password},
</if>
</trim>
與上面的set語(yǔ)句對(duì)比,prefix="SET" 是為SQL語(yǔ)句設(shè)置前綴,suffixOverrides是自動(dòng)判斷后綴 "," suffix="WHERE id = #{id}" 是自動(dòng)在加上后綴。
如果password和userName都有值,則該條sql語(yǔ)句為:
UPDATE User SET userName = ?, password=? WHERE id = ?
foreach的用法
foreach元素的屬性主要有 item,index,collection,open,separator,close。
item
循環(huán)體中的具體對(duì)象。支持屬性的點(diǎn)路徑訪問,如
item.age,item.info.details。 具體說明:在list和數(shù)組中是其中的對(duì)象,在map中是value。 該參數(shù)為必選。
collection
要做foreach的對(duì)象,作為入?yún)r(shí),List<?>對(duì)象默認(rèn)用list代替作為鍵,數(shù)組對(duì)象有array代替作為鍵,Map對(duì)象用map代替作為鍵。 當(dāng)然在作為入?yún)r(shí)可以使用@Param("keyName")來設(shè)置鍵,設(shè)置keyName后,list,array,map將會(huì)失效。 除了入?yún)⑦@種情況外,還有一種作為參數(shù)對(duì)象的某個(gè)字段的時(shí)候。舉個(gè)例子: 如果User有屬性List ids。入?yún)⑹荱ser對(duì)象,那么這個(gè)collection = "ids" 如果User有屬性Ids ids;其中Ids是個(gè)對(duì)象,Ids有個(gè)屬性List id;入?yún)⑹荱ser對(duì)象,那么collection = "ids.id" 上面只是舉例,具體collection等于什么,就看你想對(duì)那個(gè)元素做循環(huán)。 該參數(shù)為必選。
separator
元素之間的分隔符,例如在in()的時(shí)候,separator=","會(huì)自動(dòng)在元素中間用“,“隔開,避免手動(dòng)輸入逗號(hào)導(dǎo)致sql錯(cuò)誤,如in(1,2,)這樣。該參數(shù)可選。
index
在list和數(shù)組中,index是元素的序號(hào),在map中,index是元素的key,該參數(shù)可選。
open
foreach代碼的開始符號(hào),一般是(和close=")"合用。常用在in(),values()時(shí)。該參數(shù)可選。
close
foreach代碼的關(guān)閉符號(hào),一般是)和open="("合用。常用在in(),values()時(shí)。該參數(shù)可選。
需要注意一下collection不同情況下的用法
- 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)List的時(shí)候,collection屬性值為list
- 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)array數(shù)組的時(shí)候,collection的屬性值為array
- 如果傳入的參數(shù)是多個(gè)的時(shí)候,我們就需要把它們封裝成一個(gè)Map了,當(dāng)然單參數(shù)也可
相關(guān)案例:
<select id="countByUserList" resultType="_int" parameterType="list">
select count(*) from users
<where>
id in
<foreach item="item" collection="list" separator="," open="(" close=")" index="">
#{item.id, jdbcType=NUMERIC}
</foreach>
</where>
</select>
![Uploading fc7388015ca53d2bbc8d4309f8527919_785719.jpg . . .]
上面的sql語(yǔ)句等價(jià)與
select count(*) from users WHERE id in ( ? , ? )
傳入map類型的參數(shù)時(shí):
<insert id="ins_string_string">
insert into string_string (key, value) values
<foreach item="item" index="key" collection="map"
open="" separator="," close="">(#{key}, #{item})</foreach>
</insert>
表中需要兩個(gè)值,正好和K,V對(duì)應(yīng),因而map中的一個(gè)K,V就對(duì)應(yīng)一條數(shù)據(jù),如果map中有多個(gè)K,V,就會(huì)保存多個(gè)結(jié)果
對(duì)應(yīng)的sql語(yǔ)句為:
insert into string_string (key, value) values (?, ?) , (?, ?)