MyBatis動(dòng)態(tài)SQL標(biāo)簽的用法詳解
1.MyBatis動(dòng)態(tài)SQL
MyBatis 的強(qiáng)大特性之一便是它的動(dòng)態(tài) SQL,即拼接SQL字符串。如果你有使用 JDBC 或其他類似框架的經(jīng)驗(yàn),你就能體會(huì)到根據(jù)不同條件拼接 SQL 語(yǔ)句有多么痛苦。拼接的時(shí)候要確保不能忘了必要的空格,還要注意省掉列名列表最后的逗號(hào)。利用動(dòng)態(tài) SQL 這一特性可以徹底擺脫這種痛苦。
通常使用動(dòng)態(tài) SQL 不可能是獨(dú)立的一部分,MyBatis 當(dāng)然使用一種強(qiáng)大的動(dòng)態(tài) SQL 語(yǔ)言來(lái)改進(jìn)這種情形,這種語(yǔ)言可以被用在任意的 SQL 映射語(yǔ)句中。
動(dòng)態(tài) SQL 元素和使用 JSTL 或其他類似基于 XML 的文本處理器相似。在 MyBatis 之前的版本中,有很多的元素需要來(lái)了解。MyBatis 3 大大提升了它們,現(xiàn)在用不到原先一半的元素就可以了。MyBatis 采用功能強(qiáng)大的基于 OGNL 的表達(dá)式來(lái)消除其他元素。
2.動(dòng)態(tài)SQL標(biāo)簽:if,choose (when, otherwise),trim (where, set),foreach
2.1 if標(biāo)簽:直接上代碼
<select id="queryByIdAndTitle" resultType="Blog"> SELECT * FROM BLOG WHERE 1=1 <if test="id!= null and title!=null"> AND id=#{id} and title=#{title} </if> </select>
注:if標(biāo)簽一般用于非空驗(yàn)證,如上例,若id為空,if標(biāo)簽里的代碼,將不會(huì)執(zhí)行,反之,則會(huì)執(zhí)行。
2.2 choose(when,otherwise)標(biāo)簽:直接上代碼
<select id="queryBy" resultType="Blog"> SELECT * FROM BLOG WHERE 1=1 <choose> <when test="title != null"> AND title like #{title} </when> <otherwise> AND id= 1 </otherwise> </choose> </select>
注:choose(when,otherwise)標(biāo)簽相當(dāng)于switch(case,default) ,如上例,若title 為空,when標(biāo)簽里的代碼,將不會(huì)執(zhí)行,默認(rèn)執(zhí)行otherwise標(biāo)簽里面的代碼。
2.3 trim(where,set)標(biāo)簽:直接上代碼
<select id="queryBy" resultType="com.scme.pojo.User" parameterType="com.scme.pojo.User"> select * from user <where> <if test="username!=null and password!=null"> and username=#{username} and password=#{password} </if> </where> </select>
注:假設(shè)上例傳入的username,password不為空,代碼就可以運(yùn)行成功!但朋友們可能有疑問(wèn)了,實(shí)際上執(zhí)行的sql語(yǔ)句是什么呢?其實(shí),sql為:select * from user
where username=? and password=? 朋友們是否發(fā)現(xiàn),where標(biāo)簽代替了sql中where關(guān)鍵字,但if中的and不見(jiàn)了。其實(shí)where標(biāo)簽可以自動(dòng)去除是“AND”或“OR”開(kāi)頭的sql中的“AND”或“OR”關(guān)鍵字。
如果 where 元素沒(méi)有按正常套路出牌,我們還是可以通過(guò)自定義 trim 元素來(lái)定制sql,實(shí)現(xiàn)where標(biāo)簽的效果。代碼如下:
<select id="queryBy" resultType="com.scme.pojo.User" parameterType="com.scme.pojo.User"> select * from user <trim prefix="WHERE" prefixOverrides="AND |OR "> <if test="username!=null and password!=null"> and username=#{username} and password=#{password} </if> </trim> <!-- 效果同上 <where> <if test="username!=null and password!=null"> and username=#{username} and password=#{password} </if> </where> --> </select>
set標(biāo)簽,代碼如下:
<update id="updateUser" parameterType="com.scme.pojo.User"> update user <set> <if test="username!=null"> username=#{username} </if> </set> <where> <if test="id!=null"> id=#{id} </if> </where> </update>
注:set標(biāo)簽功能和where標(biāo)簽差不多,set標(biāo)簽代替了sql中set關(guān)鍵字,set標(biāo)簽可以自動(dòng)去除sql中的多余的“,”
同理,trim標(biāo)簽也可以實(shí)現(xiàn)set標(biāo)簽的功能
<update id="updateUser" parameterType="com.scme.pojo.User"> update user <trim prefix="set" prefixOverrides=","> <if test="username!=null"> username=#{username} </if> </trim> <where> <if test="id!=null"> id=#{id} </if> </where> </update>
2.4 foreach標(biāo)簽:foreach標(biāo)簽實(shí)現(xiàn)批量刪除,直接上代碼
<delete id="batchDelete" parameterType="java.lang.String"> delete from user where id in <foreach item="id" index="index" collection="list" open="(" separator="," close=")"> #{id} </foreach> </delete >
注:foreach標(biāo)簽可迭代任何對(duì)象(如列表、集合等)和任何的字典或者數(shù)組對(duì)象傳遞給foreach作為集合參數(shù),當(dāng)使用可迭代對(duì)象或者數(shù)組時(shí),index是當(dāng)前迭代的次數(shù),item的值是本次迭代獲取的元素。當(dāng)使用字典(或者M(jìn)ap.Entry對(duì)象的集合)時(shí),index是鍵,item是值。collection標(biāo)簽可以填('list','array','map')。
foreach元素的屬性主要有 item,index,collection,open,separator,close。
item表示集合中每一個(gè)元素進(jìn)行迭代時(shí)的別名;
index指 定一個(gè)名字,用于表示在迭代過(guò)程中,每次迭代到的位置;
open表示該語(yǔ)句以什么開(kāi)始,
separator表示在每次進(jìn)行迭代之間以什么符號(hào)作為分隔符;
close表示以什么結(jié)束。
3.bind
bind 元素可以從 OGNL 表達(dá)式中創(chuàng)建一個(gè)變量并將其綁定到上下文。比如:
<select id="selectBlogsLike" resultType="Blog"> <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{pattern} </select>
4.Multi-db vendor support
一個(gè)配置了“_databaseId”變量的 databaseIdProvider 對(duì)于動(dòng)態(tài)代碼來(lái)說(shuō)是可用的,這樣就可以根據(jù)不同的數(shù)據(jù)庫(kù)廠商構(gòu)建特定的語(yǔ)句。比如下面的例子:
<insert id="insert"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> <if test="_databaseId == 'oracle'"> select seq_users.nextval from dual </if> <if test="_databaseId == 'db2'"> select nextval for seq_users from sysibm.sysdummy1" </if> </selectKey> insert into users values (#{id}, #{name}) </insert>
動(dòng)態(tài) SQL 中可插拔的腳本語(yǔ)言
MyBatis 從 3.2 開(kāi)始支持可插拔的腳本語(yǔ)言,因此你可以在插入一種語(yǔ)言的驅(qū)動(dòng)(language driver)之后來(lái)寫基于這種語(yǔ)言的動(dòng)態(tài) SQL 查詢。
可以通過(guò)實(shí)現(xiàn)下面接口的方式來(lái)插入一種語(yǔ)言:
public interface LanguageDriver { ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql); SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType); SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType); }
一旦有了自定義的語(yǔ)言驅(qū)動(dòng),你就可以在 mybatis-config.xml 文件中將它設(shè)置為默認(rèn)語(yǔ)言:
<typeAliases> <typeAlias type="org.sample.MyLanguageDriver" alias="myLanguage"/> </typeAliases> <settings> <setting name="defaultScriptingLanguage" value="myLanguage"/> </settings>
除了設(shè)置默認(rèn)語(yǔ)言,你也可以針對(duì)特殊的語(yǔ)句指定特定語(yǔ)言,這可以通過(guò)如下的 lang 屬性來(lái)完成:
<select id="selectBlog" lang="myLanguage"> SELECT * FROM BLOG </select>
或者在你正在使用的映射中加上注解 @Lang 來(lái)完成:
public interface Mapper { @Lang(MyLanguageDriver.class) @Select("SELECT * FROM BLOG") List<Blog> selectBlog();
注意 可以將 Apache Velocity 作為動(dòng)態(tài)語(yǔ)言來(lái)使用,更多細(xì)節(jié)請(qǐng)參考 MyBatis-Velocity 項(xiàng)目。
到此這篇關(guān)于MyBatis動(dòng)態(tài)SQL標(biāo)簽的用法詳解的文章就介紹到這了,更多相關(guān)MyBatis動(dòng)態(tài)SQL標(biāo)簽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot之groups應(yīng)對(duì)不同的Validation規(guī)則自定義方式
這篇文章主要介紹了SpringBoot之groups應(yīng)對(duì)不同的Validation規(guī)則自定義方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10java環(huán)境中的JDK、JVM、JRE詳細(xì)介紹
這篇文章主要介紹了java環(huán)境中的JDK、JVM、JRE詳細(xì)介紹的相關(guān)資料,對(duì)于初學(xué)者還是有必要了解下,細(xì)致說(shuō)明他們是什么,需要的朋友可以參考下2016-11-115分鐘快速學(xué)會(huì)spring boot整合Mybatis的方法
這篇文章主要給大家介紹了如何通過(guò)5分鐘快速學(xué)會(huì)spring boot整合Mybatis的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12spring容器啟動(dòng)實(shí)現(xiàn)初始化某個(gè)方法(init)
這篇文章主要介紹了spring容器啟動(dòng)實(shí)現(xiàn)初始化某個(gè)方法(init),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(15)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-07-07springboot整合security和vue的實(shí)踐
本文主要介紹了springboot整合security和vue的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09