日本国产欧美大码A视频 _国产高颜值极品在线视频_色偷偷亚洲第一综合网_国产精品一二三社区视频_久久久青草视频

IT培訓(xùn)-高端面授IT培訓(xùn)機(jī)構(gòu)
云和教育:云和數(shù)據(jù)集團(tuán)高端IT職業(yè)教育品牌
  • 國(guó)家級(jí)
    全民數(shù)字素養(yǎng)與技能培訓(xùn)基地
  • 河南省
    第一批產(chǎn)教融合型企業(yè)建設(shè)培育單位
  • 鄭州市
    數(shù)字技能人才(碼農(nóng))培養(yǎng)評(píng)價(jià)聯(lián)盟
當(dāng)前位置:
首頁新聞資訊IT資訊正文

云和數(shù)據(jù)大咖分享:Mybatis動(dòng)態(tài)SQL

  • 發(fā)布時(shí)間:
    2020-09-05
  • 版權(quán)所有:
    云和教育
  • 分享:
MyBatis 令人喜歡的一大特性就是動(dòng)態(tài) SQL。在使用 JDBC 的過程中, 根據(jù)條件進(jìn)行 SQL 的拼接是很麻煩且很容易出錯(cuò)的。
MyBatis 動(dòng)態(tài) SQL 的出現(xiàn), 解決了這個(gè)麻煩。
動(dòng)態(tài)SQl是MyBatis的強(qiáng)大特性之一,可以完成對(duì)SQL語句的動(dòng)態(tài)組裝。
比如說傳入一個(gè)User對(duì)象,要根據(jù)這個(gè)User中的數(shù)據(jù)查詢用戶的完整信息:
如果User對(duì)象中只有name屬性有值,sql語句是:select * from user_tb ?where name=#{name}

如果User對(duì)象中只有tel屬性有值,sql語句是:select * from user_tb where tel=#{tel}

如果User對(duì)象的name、tel都有值,sql語句是:select * from user_tb where name=#{name} and tel=#{tel}

有時(shí)候sql語句不是一成不變的,要根據(jù)傳入的數(shù)據(jù)動(dòng)態(tài)生成要執(zhí)行的sql語句,動(dòng)態(tài)sql就適合這種情況。
最好將日志的控制臺(tái)輸出級(jí)別設(shè)置為DEBUG,這樣在控臺(tái)能看到SQL語句。
1.MyBatis中的動(dòng)態(tài)sql元素

<if>? 相當(dāng)于java中的if,用于單分支的條件判斷

<choose>、<when>、<otherwise>? 相當(dāng)于java中的switch…case…default,用于多分支的條件判斷,從多個(gè)選項(xiàng)中選擇一個(gè)

<foreach> 循環(huán),常和sql的in語句搭配使用

<where>、<trim>、<set>? 輔助元素,用于一些處理sql拼裝、特殊字符的問題

2.<where>、<if>的使用

xml

<select id=”queryUser” parameterType=”user” resultType=”user”>

SELECT * FROM user_tb

<where>

<if test=”name!=null and name!=””>

name=#{name}

</if>

<if test=”tel!=null and tel!=””>

AND tel=#{tel}

</if>

</where>

</select>

<where>相當(dāng)于sql語句中的關(guān)鍵字WHERE。

<if>中的test表示條件,條件成立就把元素體中的字符串拼接到sql語句中,否則不拼接。

> test屬性的注意點(diǎn)

> 相等判斷:==,!=

> 邏輯與:只能用and,不能用&&

> 邏輯或:or、||均可

tel不進(jìn)行數(shù)學(xué)運(yùn)算,使用字符串類型。

<where>中有<if>成立時(shí),<where>才會(huì)在sql語句中添加WHERE關(guān)鍵字,否則不添加。

<where>會(huì)自動(dòng)剔除元素體中多余的AND、OR。

比如傳入的User對(duì)象只設(shè)置了tel,拼接的sql語句是:SELECT ?*? FROM ?user_tb ?WHERE ?AND ?tel=#{tel},<where>會(huì)自動(dòng)剔除多余的AND。

不使用<where>的寫法:

xml

<select id=”queryUser” parameterType=”user” resultType=”user”>

SELECT * FROM user_tb? WHERE 1=1

<if test=”name!=null and name!=””>

AND name=#{name}

</if>

<if test=”tel!=null and tel!=””>

AND tel=#{tel}

</if>

</select>

<where>會(huì)自動(dòng)去掉多余的AND,但不會(huì)自動(dòng)加上缺少的AND,我們通常在每個(gè)<if>中都加上AND,防止把AND寫掉了。

3.<trim>的使用

<trim>可以定制需要的功能,比如使用<trim>達(dá)到<where>的效果:

xml

<select id=”queryUser” parameterType=”user” resultType=”user”>

SELECT * FROM user_tb

<trim prefix=”WHERE” prefixOverrides=”AND”>

<if test=”name!=null and name!=””>

name=#{name}

</if>

<if test=”tel!=null and tel!=””>

AND tel=#{tel}

</if>

</trim>

</select>

prefix會(huì)在這段字符串之前加上指定的前綴,如果里面的<if>都不滿足條件,則不加前綴。

prefixOverrides指定要去除的多余的字符串。

4.<choose>、<when>、<otherwise>的使用

有時(shí)候我們只需要從多個(gè)選項(xiàng)中選擇一個(gè),比如登錄教務(wù)系統(tǒng),讓你選擇角色:數(shù)據(jù)庫管理員、教職工、學(xué)生:

xml

<select id=”queryPwd” parameterType=”user” resultType=”string”>

SELECT password FROM user_tb WHERE name=#{name}

<choose>

<when test=”role==’admin'”>

AND role=’admin’

</when>

<when test=”role==’teacher'”>

AND role=’teacher’

</when>

<when test=”role==’student'”>

AND role=’student’

</when>

</choose>

</select>

傳入的值是admin、teacher、student,數(shù)據(jù)庫中的role字段也是這幾個(gè)值,這種傳入的值和數(shù)據(jù)庫中存儲(chǔ)的值一致的可以直接這樣寫:

xml

<select id=”queryPwd” parameterType=”user” resultType=”string”>

SELECT password FROM user_tb WHERE name=#{name} AND role=#{role}

</select>

如果不一致,比如性別,傳入的是male、female,數(shù)據(jù)庫中存儲(chǔ)的是0、1,就需要使用<choose>轉(zhuǎn)換一下。

xml

<choose>

<when test=””>

</when>

<when test=””>

</when>

<otherwise>

</otherwise>

</choose>

<choose>相當(dāng)于switch,<when>相當(dāng)于case,<otherwise>相當(dāng)于default。

5.<set>的使用

更新操作傳入一個(gè)pojo類的對(duì)象,但我們并不知道哪些屬性是有值的(需要更新的),不能更新全部字段,因?yàn)橛械淖侄螞]有手動(dòng)賦值,不能用JVM賦的null、0去覆蓋數(shù)據(jù)表中原來的值。

<set>可解決此問題:

xml

<select id=”updateUser” parameterType=”user”>

UPDATE user_tb

<set>

<if test=”name!=null and name!=””>

name=#{name},

</if>

<if test=”tel!=null and tel!=””>

tel=#{tel},

</if>

<if test=”address!=null and address!=””>

name=#{name},

</if>

</set>

where id=#{id}

</select>

<set>用于傳入pojo類型,更新數(shù)據(jù)表的多個(gè)字段。先判斷字段是否有值,有值才更新該字段。

<set>用于更新操作,會(huì)自動(dòng)在這段字符串前面加sql關(guān)鍵字“SET”(里面有<if>為真),并自動(dòng)去除多余的逗號(hào)(一般自己寫第一個(gè)<if>,然后copy下來改,最后面往往會(huì)多一個(gè)逗號(hào))。

如果里面的<if>都為假,即沒有要更新的字段,不會(huì)自動(dòng)在前面加”SET”,此時(shí)這個(gè)update語句有語法錯(cuò)誤,會(huì)報(bào)錯(cuò),所以要保證至少有一個(gè)字段需要更新。

6.<foreach>的使用

<foreach>用于迭代集合、數(shù)組,常配合sql的關(guān)鍵字in使用,用于增刪查改的批量操作。

示例:按照手機(jī)號(hào)隨機(jī)抽取3位幸運(yùn)觀眾(根據(jù)手機(jī)號(hào)碼查詢用戶信息)——批量查。

xml

<select id=”queryUser” parameterType=”list” resultType=”user”>

SELECT * FROM user_tb WHERE tel IN

<foreach collection=”list” index=”index” item=”item” open=”(” separator=”,” close=”)”>

#{item}

</foreach>

</select>

java

ArrayList<String> telList = new ArrayList<>();

telList.add(“110”);

telList.add(“119”);

telList.add(“120”);

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

List<User> userList = mapper.queryUser(telList);

System.out.println(userList);

?collection ??要迭代的數(shù)據(jù)類型,數(shù)組=>array,List=>list,Map=>Map的key的數(shù)據(jù)類型。使用數(shù)組容易出錯(cuò),盡量用List代替數(shù)組。

index? ?本次迭代的下標(biāo),指定一個(gè)臨時(shí)變量表示下標(biāo)

item? ?本次迭代的元素,指定一個(gè)臨時(shí)變量表示本次迭代的元素

open? ?拼接這段字符串時(shí)以什么開頭

close? 拼接這段字符串以什么結(jié)尾

separator? ?迭代的元素之間用什么連接(分隔)

collection是必需的,其余均可選。

更嚴(yán)謹(jǐn)?shù)膶懛ǎ?/p>

xml

<select id=”queryUser” parameterType=”list” resultType=”user”>

SELECT * FROM user_tb WHERE tel IN

<if test=”list!=null and list.size>0″>

<foreach collection=”list” index=”index” item=”item” open=”(” separator=”,” close=”)”>

#{item}

</foreach>

</if>

</select>

如果傳入的是List類型,要使用List對(duì)象本身時(shí),約定使用list表示List對(duì)象本身。

文/云和數(shù)據(jù)高級(jí)JAVA開發(fā)工程師