MyBatis中關(guān)于SQL的寫法總結(jié)
最近MyBatis使用較多,在這里簡(jiǎn)單總結(jié)一下MyBatis的sql寫法
說(shuō)簡(jiǎn)單一點(diǎn)mybatis就是寫原?sql,官方都說(shuō)了 mybatis 的動(dòng)態(tài)sql語(yǔ)句是基于OGNL表達(dá)式的??梢苑奖愕脑?sql 語(yǔ)句中實(shí)現(xiàn)某些邏輯.
總體說(shuō)來(lái)mybatis 動(dòng)態(tài)SQL 語(yǔ)句主要有以下幾類:
if
語(yǔ)句 (簡(jiǎn)單的條件判斷)choose
(when,otherwize) ,相當(dāng)于java 語(yǔ)?中的 switch ,與 jstl 中的choose 很類似.trim
(對(duì)包含的內(nèi)容加上 prefix,或者 suffix 等,前綴,后綴)where
(主要是?來(lái)簡(jiǎn)化sql語(yǔ)句中where條件判斷的,能智能的處理 and or ,不必?fù)?dān)心多余導(dǎo)致語(yǔ)法誤)set
(主要?于更新時(shí))foreach
(在實(shí)現(xiàn) mybatis in 語(yǔ)句查詢時(shí)特別有用)
一、MyBatis – if 語(yǔ)句
< select id="dynamicIfTest" parameterType="Blog" resultType="Blog"> ?? ?select * ?from t_blog ?where 1 = 1 ?? ?<if test="title != null"> ?? ??? ?and title = ?#{title} ?? ?</if> ?? ?<if test="content != null"> ?? ??? ?and content = ?#{content} ?? ?</if> ?? ?<if test="owner != null"> ?? ??? ?and owner = ?#{owner} ?? ?</if> </ select>
if語(yǔ)句十分好理解,只有提供title,content,owener,這三個(gè)參數(shù),才會(huì)返回滿足這些條件的所有結(jié)果,這是一個(gè)非常有用的功能,如果使用JDBC就需要拼SQL語(yǔ)句,是非常麻煩的,相比較而言,MyBatis提供的這種動(dòng)態(tài)Sql就非常的簡(jiǎn)單
二、MyBatis --choose 語(yǔ)句
相當(dāng)于java 語(yǔ)?中的 switch ,與 jstl 中的choose 很類似.
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog"> ?? ?select * ?from t_blog where 1 = 1 ?? ?<choose> ?? ??? ?<when test="title != null"> ?? ??? ??? ?and title = ?#{title} ?? ??? ?</when> ?? ??? ?<when test="content != null"> ?? ??? ??? ?and content = ?#{content} ?? ??? ?</when> ?? ??? ?<otherwise> ?? ??? ??? ?and owner = "owner1" ?? ??? ?</otherwise> ?? ?</choose> </select>
when元素表?當(dāng)when中的條件滿?的時(shí)候就輸出其中的內(nèi)容,跟JAVA中的switch效果差不多的是按條件的順序,當(dāng)when中有條件滿?的時(shí)候,就會(huì)跳出choose,即所有的when和otherwise條件中,只有個(gè)會(huì)輸出,當(dāng)所有的我很條件都不滿?的時(shí)候就輸出otherwise中的內(nèi)容。
所以上述語(yǔ)句的意思?常簡(jiǎn)單,當(dāng)title!=null的時(shí)候就輸出and titlte = #{title},不再往下判斷條件,當(dāng)title為空且content!=null的時(shí)候就出and content = #{content},當(dāng)所有條件都不滿?的時(shí)候就輸出otherwise中的內(nèi)容。
三、MyBatis – trim
對(duì)包含的內(nèi)容加上 prefix,或者 suffix 等,前綴,后綴
<select id="dynamicTrimTest" parameterType="Blog" resultType="Blog"> ?? ?select * ?from t_blog ?? ?<trim prefix="where" prefixOverrides="and |or"> ?? ??? ?<if test="title != null"> ?? ??? ??? ?title = ?#{title} ?? ??? ?</if> ?? ??? ?<if test="content != null"> ?? ??? ??? ?and content = ?#{content} ?? ??? ?</if> ?? ??? ?<if test="owner != null"> ?? ??? ??? ?or owner = ?#{owner} ?? ??? ?</if> ?? ?</trim> </select>
后綴,與之對(duì)應(yīng)的屬性是prefix和suffix;可以把包含內(nèi)容的?部某些內(nèi)容覆蓋,即忽略,也可以把尾的某些內(nèi)容覆蓋,對(duì)應(yīng)的屬性是prefixOverrides和suffixOverrides;正因?yàn)閠rim有這樣的功能,所以我們可以?常簡(jiǎn)單的利?trim來(lái)代替where元素的功能。
四、MyBatis – where
主要是?來(lái)簡(jiǎn)化sql語(yǔ)句中where條件判斷的,能智能的處理 and or 條件
<select id="dynamicWhereTest" parameterType="Blog" resultType="Blog"> ?? ?select * ?from t_blog ?? ?<where> ?? ??? ?<if test="title != null"> ?? ??? ??? ?title = ?#{title} ?? ??? ?</if> ?? ??? ?<if test="content != null"> ?? ??? ??? ?and content = ?#{content} ?? ??? ?</if> ?? ??? ?<if test="owner != null"> ?? ??? ??? ?and owner = ?#{owner} ?? ??? ?</if> ?? ?</where> </ select>
where元素的作?是會(huì)在寫?where元素的地?輸出?個(gè)where,另外?個(gè)好處是你不需要考慮where素??的條件輸出是什么樣?的,MyBatis會(huì)智能的幫你處理,如果所有的條件都不滿?那么MyBatis就查出所有的記錄,如果輸出后是and 開頭的,MyBatis會(huì)把第?個(gè)and忽略,當(dāng)然如果是or開頭的MyBatis也會(huì)把它忽略;此外,在where元素中你不需要考慮空格的問題,MyBatis會(huì)智能的幫你加上。
像上述?中,如果title=null, ?content != null,那么輸出的整個(gè)語(yǔ)句會(huì)是select * fromt_blog where content = {content},?不是select * from t_blog where and content = #{content},因?yàn)镸yBatis會(huì)智能的把?個(gè)and 或 or 給忽略。
五、MyBatis – set
主要?于更新時(shí)
<update id="dynamicSetTest" parameterType="Blog"> ?? ?update t_blog ?? ?<set> ?? ??? ?<if test="title != null"> ?? ??? ??? ?title = ?#{title}, ?? ??? ?</if> ?? ??? ?<if test="content != null"> ?? ??? ??? ?content = ?#{content}, ?? ??? ?</if> ?? ??? ?<if test="owner != null"> ?? ??? ??? ?owner = ?#{owner} ?? ??? ?</if> ?? ?</set> ?? ?where id = ?#{id} </update>
set元素主要是?在更新操作的時(shí)候,它的主要功能和where元素其實(shí)是差不多的,主要是在包含的語(yǔ)前輸出?個(gè)set,然后如果包含的語(yǔ)句是以逗號(hào)結(jié)束的話將會(huì)把該逗號(hào)忽略,如果set包含的內(nèi)容為空的話會(huì)出錯(cuò)。
有了set元素我們就可以動(dòng)態(tài)的更新那些修改了的字段。
六、MyBatis – foreach
在實(shí)現(xiàn) mybatis in 語(yǔ)句查詢時(shí)特別有?
<select id="queryById" resultMap="BaseReslutMap" > ?? ?select * FROM entity ?? ?where id ?in ?? ?<foreach collection="userids" item="userid" index="index" open="(" separator="," close=")"> ?? ??? ?#{userid} ?? ?</foreach> </select>
foreach的主要?在構(gòu)建in條件中,它可以在SQL語(yǔ)句中進(jìn)?迭代?個(gè)集合。
foreach元素的屬性主要有item,index,collection,open,separator,close。
item表?集合中每?個(gè)元素進(jìn)?迭代時(shí)的別名index指定?個(gè)名字,?于表?在迭代過(guò)程中,每次迭代到的位置,open表?該語(yǔ)句以什么開始,separator?在每次進(jìn)?迭代之間以什么符號(hào)作為分隔符,close表?以什么結(jié)束,在使?foreach的時(shí)候最關(guān)鍵的也最容易出錯(cuò)的就是collection屬性,該屬性是必須指定的,但是在不同情況下,該屬性的值是不?樣的,主要有?下3種情況:
- 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ù)也可以封裝map實(shí)際上如果你在傳?參數(shù)的時(shí)候,在MyBatis??也是會(huì)把它封裝成?個(gè)Map的,map的key就是參數(shù)名所以這個(gè)時(shí)候collection屬性值就是傳?的List或array對(duì)象在??封裝的map??的key。
七、MyBatis – concat
模糊查詢
<select id="queryById" resultMap="BascResultMap" parameterType="entity"> ?? ?SELECT * ?from entity ?? ?<where> ?? ??? ?<if test="name!=null"> ?? ??? ??? ?name like ?concat('%',concat(#{name},'%')) ?? ??? ?</if> ?? ?</where> </select>
八、MyBatis – sql片段
sql?段標(biāo)簽 :通過(guò)該標(biāo)簽可定義能復(fù)?的sql語(yǔ)句?段,在執(zhí)?sql語(yǔ)句標(biāo)簽中直接引?即可。
這既可以提?編碼效率,還能有效簡(jiǎn)化代碼,提?可讀性。
<!--定義sql?段--> <sql id="orderAndItem"> ?? ?o.order_id,o.cid,o.address,o.create_date,o.orderitem_id,i.orderitem_id,i.product_id,i.count </sql> <select id="findOrderAndItemsByOid" parameterType="java.lang.String" resultMap="BaseResultMap"> ?? ?select ?? ?<!--引?sql?段--> ?? ?<include refid="orderAndItem" /> ?? ?from ordertable o ?? ?join orderitem i on o.orderitem_id = i.orderitem_id ?? ?where o.order_id = #{orderId} </select>
需要配置的屬性:id="" >>>表?需要改sql語(yǔ)句?段的唯?標(biāo)識(shí)
引用:通過(guò) 標(biāo)簽引?,refid="" 中的值指向需要引?的 中的id=“”屬性
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot實(shí)現(xiàn)密碼的加密解密
這篇文章主要為大家詳細(xì)介紹了Springboot實(shí)現(xiàn)密碼的加密解密,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11Spring mvc 實(shí)現(xiàn)用戶登錄的方法(攔截器)
這篇文章主要介紹了Spring mvc 實(shí)現(xiàn)用戶登錄的方法(攔截器),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07java實(shí)現(xiàn)事件委托模式的實(shí)例詳解
這篇文章主要介紹了java實(shí)現(xiàn)事件委托模式的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例來(lái)說(shuō)明如何實(shí)現(xiàn)改功能,希望能幫助到大家理解這樣的模式,需要的朋友可以參考下2017-08-08Java后端產(chǎn)生驗(yàn)證碼后臺(tái)驗(yàn)證功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java后臺(tái)產(chǎn)生驗(yàn)證碼后臺(tái)驗(yàn)證功能,本文文字結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06SSH框架網(wǎng)上商城項(xiàng)目第6戰(zhàn)之基于DataGrid的數(shù)據(jù)顯示
SSH框架網(wǎng)上商城項(xiàng)目第6戰(zhàn)之基于DataGrid的數(shù)據(jù)顯示,提供了豐富的選擇、排序、分組和編輯數(shù)據(jù)的功能支持,感興趣的小伙伴們可以參考一下2016-05-05解決java.sql.SQLException:?validateConnection?false問題的方法匯總(最
這篇文章主要給大家介紹了關(guān)于解決java.sql.SQLException:?validateConnection?false問題的方法匯總,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題
本篇文章主要介紹了淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題,具有一定的參考價(jià)值,有需要的可以了解一下2017-08-08