Mybatis動(dòng)態(tài)SQL

在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不同情況下的用法

  1. 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)List的時(shí)候,collection屬性值為list
  2. 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)array數(shù)組的時(shí)候,collection的屬性值為array
  3. 如果傳入的參數(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 (?, ?) , (?, ?) 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,701評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,694評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,026評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,193評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,719評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,668評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,846評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評(píng)論 1 295
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,394評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容