mybatis的動(dòng)態(tài)sql詳解(精)
MyBatis 的一個(gè)強(qiáng)大的特性之一通常是它的動(dòng)態(tài) SQL 能力。如果你有使用 JDBC 或其他 相似框架的經(jīng)驗(yàn),你就明白條件地串聯(lián) SQL 字符串在一起是多么的痛苦,確保不能忘了空 格或在列表的最后省略逗號(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)了解。MyBatis3大大提升了它們,現(xiàn)在用不到原先一半 的元素就能工作了。MyBatis采用功能強(qiáng)大的基于OGNL的表達(dá)式來(lái)消除其他元素。
MyBatis中用于實(shí)現(xiàn)動(dòng)態(tài)SQL的元素主要有:
if
choose(when,otherwise)
trim
where
set
foreach
if就是簡(jiǎn)單的條件判斷,利用if語(yǔ)句我們可以實(shí)現(xiàn)某些簡(jiǎn)單的條件選擇。
先來(lái)看如下一個(gè)例子:
Xml代碼
<select id="dynamicIfTest" parameterType="Blog" resultType="Blog"> select * from t_blog where 11 = 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>
這條語(yǔ)句的意思非常簡(jiǎn)單,如果你提供了title參數(shù),那么就要滿足title=#{title},同樣如果你提供了Content和Owner的時(shí)候,它們也需要滿足相應(yīng)的條件,之后就是返回滿足這些條件的所有Blog,這是非常有用的一個(gè)功能,以往我們使用其他類型框架或者直接使用JDBC的時(shí)候, 如果我們要達(dá)到同樣的選擇效果的時(shí)候,我們就需要拼SQL語(yǔ)句,這是極其麻煩的,比起來(lái),上述的動(dòng)態(tài)SQL就要簡(jiǎn)單多了。
choose元素的作用就相當(dāng)于JAVA中的switch語(yǔ)句,基本上跟JSTL中的choose的作用和用法是一樣的,通常都是與when和otherwise搭配的。
看如下一個(gè)例子:
Xml代碼
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog"> select * from t_blog where 11 = 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)容。
where語(yǔ)句的作用主要是簡(jiǎn)化SQL語(yǔ)句中where中的條件判斷的,先看一個(gè)例子,再解釋一下where的好處。
Xml代碼
<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就會(huì)查出所有的記錄,如果輸出后是and 開(kāi)頭的,MyBatis會(huì)把第一個(gè)and忽略,當(dāng)然如果是or開(kāi)頭的,MyBatis也會(huì)把它忽略;此外,在where元素中你不需要考慮空格的問(wèn)題,MyBatis會(huì)智能的幫你加上。像上述例子中,如果title=null, 而content != null,那么輸出的整個(gè)語(yǔ)句會(huì)是select * from t_blog where content = #{content},而不是select * from t_blog where and content = #{content},因?yàn)镸yBatis會(huì)智能的把首個(gè)and 或 or 給忽略。
trim元素的主要功能是可以在自己包含的內(nèi)容前加上某些前綴,也可以在其后加上某些后綴,與之對(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元素的功能,示例代碼如下:
Xml代碼
<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>
set元素主要是用在更新操作的時(shí)候,它的主要功能和where元素其實(shí)是差不多的,主要是在包含的語(yǔ)句前輸出一個(gè)set,然后如果包含的語(yǔ)句是以逗號(hào)結(jié)束的話將會(huì)把該逗號(hào)忽略,如果set包含的內(nèi)容為空的話則會(huì)出錯(cuò)。有了set元素我們就可以動(dòng)態(tài)的更新那些修改了的字段。下面是一段示例代碼:
Xml代碼
<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中一個(gè)條件都不滿足,即set中包含的內(nèi)容為空的時(shí)候就會(huì)報(bào)錯(cuò)。
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ǔ)句以什么開(kāi)始,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í)際上如果你在傳入?yún)?shù)的時(shí)候,在MyBatis里面也是會(huì)把它封裝成一個(gè)Map的,map的key就是參數(shù)名,所以這個(gè)時(shí)候collection屬性值就是傳入的List或array對(duì)象在自己封裝的map里面的key
下面分別來(lái)看看上述三種情況的示例代碼:
1.單參數(shù)List的類型:
Xml代碼
<select id="dynamicForeachTest" resultType="Blog"> select * from t_blog where id in <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </select>
上述collection的值為list,對(duì)應(yīng)的Mapper是這樣的
Java代碼
public List<Blog> dynamicForeachTest(List<Integer> ids);
測(cè)試代碼:
Java代碼
@Test public void dynamicForeachTest() { SqlSession session = Util.getSqlSessionFactory().openSession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); List<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(3); ids.add(6); List<Blog> blogs = blogMapper.dynamicForeachTest(ids); for (Blog blog : blogs) System.out.println(blog); session.close(); }
2.單參數(shù)array數(shù)組的類型:
Xml代碼
<select id="dynamicForeach2Test" resultType="Blog"> select * from t_blog where id in <foreach collection="array" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </select>
上述collection為array,對(duì)應(yīng)的Mapper代碼:
Java代碼
public List<Blog> dynamicForeach2Test(int[] ids);
對(duì)應(yīng)的測(cè)試代碼:
Java代碼
@Test public void dynamicForeach2Test() { SqlSession session = Util.getSqlSessionFactory().openSession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); int[] ids = new int[] {1,3,6,9}; List<Blog> blogs = blogMapper.dynamicForeach2Test(ids); for (Blog blog : blogs) System.out.println(blog); session.close(); }
3.自己把參數(shù)封裝成Map的類型
Xml代碼
<select id="dynamicForeach3Test" resultType="Blog"> select * from t_blog where title like "%"#{title}"%" and id in <foreach collection="ids" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </select>
上述collection的值為ids,是傳入的參數(shù)Map的key,對(duì)應(yīng)的Mapper代碼:
Java代碼
public List<Blog> dynamicForeach3Test(Map<String, Object> params);
對(duì)應(yīng)測(cè)試代碼:
Java代碼
@Test public void dynamicForeach3Test() { SqlSession session = Util.getSqlSessionFactory().openSession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); final List<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(2); ids.add(3); ids.add(6); ids.add(7); ids.add(9); Map<String, Object> params = new HashMap<String, Object>(); params.put("ids", ids); params.put("title", "中國(guó)"); List<Blog> blogs = blogMapper.dynamicForeach3Test(params); for (Blog blog : blogs) System.out.println(blog); session.close(); }
以上內(nèi)容是本文敘述mybatis的動(dòng)態(tài)sql詳解,希望大家喜歡。
- MyBatis 動(dòng)態(tài)拼接Sql字符串的問(wèn)題
- MyBatis 執(zhí)行動(dòng)態(tài) SQL語(yǔ)句詳解
- Mybatis中動(dòng)態(tài)SQL,if,where,foreach的使用教程詳解
- MyBatis執(zhí)行動(dòng)態(tài)SQL的方法
- mybatis動(dòng)態(tài)sql之Map參數(shù)的講解
- MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解
- mybatis的動(dòng)態(tài)sql之if test的使用說(shuō)明
- MyBatis if choose 動(dòng)態(tài) SQL的實(shí)現(xiàn)
相關(guān)文章
Sql Server 如何去掉內(nèi)容里面的Html標(biāo)簽
這篇文章主要介紹了Sql Server 去掉內(nèi)容里邊的Html標(biāo)簽的實(shí)現(xiàn)方法,代碼超簡(jiǎn)單,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-05-05SQL Server使用Windows身份驗(yàn)證與JDBC連接數(shù)據(jù)庫(kù)的操作流程
在企業(yè)級(jí)應(yīng)用中,數(shù)據(jù)庫(kù)的安全性是非常重要的,SQL Server 提供了多種身份驗(yàn)證方式,其中 Windows 身份驗(yàn)證是一種較為安全且方便的管理方式,本文將介紹如何在 Java 中使用 JDBC 連接 SQL Server 數(shù)據(jù)庫(kù),并且通過(guò) Windows 身份驗(yàn)證來(lái)確保數(shù)據(jù)訪問(wèn)的安全性2024-12-12SQL集合函數(shù)中case when then 使用技巧
我們都知道SQL中適用case when then來(lái)轉(zhuǎn)化數(shù)據(jù)庫(kù)中的信息 比如 select (case sex when 0 then '男' else '女' end) AS sex from studentInfo2011-09-09如何得到數(shù)據(jù)庫(kù)中所有表名 表字段及字段中文描述
最近做一個(gè)項(xiàng)目,客戶希望可以自己選擇想要查看的列表,這樣就不好辦了,選擇列表的名字他們也想自定義,沒(méi)辦法這就需要查看數(shù)據(jù)表中字段,中文說(shuō)明,默認(rèn)標(biāo)志了2011-12-12SQL Server中通過(guò)reverse取某個(gè)最后一次出現(xiàn)的符號(hào)后面的內(nèi)容(字符串反轉(zhuǎn))
昨天在項(xiàng)目中遇到了一個(gè)非常簡(jiǎn)單的問(wèn)題,需要把SQL Server數(shù)據(jù)庫(kù)中保存的一段路徑地址取出其文件名,但SQL Server又沒(méi)有現(xiàn)成的方法,最后在網(wǎng)上找到這樣的一個(gè)方法,原理是先將字符串反轉(zhuǎn),取出第一個(gè)/的位置,從頭進(jìn)行截取后再次反轉(zhuǎn)2012-07-07SQL Server誤區(qū)30日談 第17天 有關(guān)頁(yè)校驗(yàn)和的誤區(qū)
從舊的實(shí)例升級(jí)上來(lái)的數(shù)據(jù)庫(kù)不會(huì)自動(dòng)開(kāi)啟頁(yè)校驗(yàn)和,除非你顯式使用ALTER DATABASE databasename SET PAGE_VERIFY CHECKSUM進(jìn)行開(kāi)啟。而在SQL Server 2005或2008新建的數(shù)據(jù)庫(kù)頁(yè)校驗(yàn)和是默認(rèn)開(kāi)啟的2013-01-01