MyBatis 的強大功能之一便是它的動態 SQL。
如果你有使用 JDBC 或其他類似框架的經驗,你就能體會到根據不同條件拼接 SQL 語句有多麼痛苦。拼接的時候要確保不能忘了必要的空格,也要注意省掉列名清單最後的逗號。利用動態 SQL 這項特性可以徹底擺脫這種痛苦。
通常使用動態 SQL 不可能是獨立的一部分,MyBatis 當然使用一種強大的動態 SQL 語言來改進這種情形,這種語言可以被用在任意的 SQL 映射語句中。
動態 SQL 元素和使用 JSTL 或其他類似基於 XML 的文字處理器相似。在 MyBatis 之前的版本中,有很多的元素需要來了解。 MyBatis 3 大大提升了它們,現在用不到原先一半的元素就可以了。 MyBatis 採用功能強大的基於 OGNL 的表達式來消除其他元素。
mybatis 的動態sql語句是基於OGNL表達式的。可以方便的在sql 語句中實作某些邏輯.總體說來mybatis 動態SQL 語句主要有以下幾類:
1. if 語句(簡單的條件判斷)
2. choose (when,otherwize) ,相當於java 語言中的switch ,與jstl 中的choose 很類似.
3. trim (對包含的內容加上prefix,或者suffix 等,前綴,後綴)
4. where (主要是用來簡化sql語句中where條件判斷的,能智能的處理and or ,不必擔心多餘導致語法錯誤)
5. set (主要用於更新時)
6. foreach (在實作mybatis in 語句查詢時特別有用)
以下分別介紹這幾種處理方式:
1. mybaits if 語句處理
<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>
這語句的意思非常簡單,如果你提供了title參數,那麼就要滿足title=#{title },同樣如果你提供了Content和Owner的時候,它們也需要滿足相應的條件,之後就是返回滿足這些條件的所有Blog,這是非常有用的一個功能,以往我們使用其他類型框架或者直接使用JDBC的時候, 如果我們要達到同樣的選擇效果的時候,我們就需要拼SQL語句,這是極其麻煩的,比起來,上述的動態SQL就要簡單多了。
2. choose (when,otherwize) ,相當於java 語言中的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元素表示當when中的條件滿足的時候就輸出其中的內容,跟JAVA中的switch效果差不多的是按照條件的順序,當when中有條件滿足的時候,就會跳出choose,即所有的when和otherwise條件中,只有一個會輸出,當所有的我很條件都不滿足的時候就輸出otherwise中的內容。所以上述語句的意思非常簡單, 當title!=null的時候就輸出and titlte = #{title},不再往下判斷條件,當title為空且content!=null的時候就輸出and content = #{ content},當所有條件都不滿足的時候就輸出otherwise中的內容。
3.trim (對包含的內容加上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>
trim元素的主要功能是可以在自己包含的內容前加上某些前綴,也可以在其後加上某些後綴,與之對應的屬性是prefix和suffix;可以把包含內容的首部某些內容覆蓋,即忽略,也可以把尾部的某些內容覆蓋,對應的屬性是prefixOverrides和suffixOverrides;正因為trim有這樣的功能,所以我們也可以非常簡單的利用trim來代替where元素的功能。
4. where (主要是用來簡化sql語句中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 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。
如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如,和 where 元素等价的自定义 trim 元素为:
...
prefixOverrides 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的)。它带来的结果就是所有在 prefixOverrides 属性中指定的内容将被移除,并且插入 prefix 属性中指定的内容。
where元素的作用是会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。像上述例子中,如果title=null, 而content != null,那么输出的整个语句会是select * from t_blog where content = #{content},而不是select * from t_blog where and content = #{content},因为MyBatis会智能的把首个and 或 or 给忽略。
5.set (主要用于更新时)
<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元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段。
6. foreach (在实现 mybatis in 语句查询时特别有用)
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
1.1.单参数List的类型
<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,对应的Mapper是这样的: public List
2.数组类型的参数
<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>
对应的Mapper: public List
3.Map 类型的参数
<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>
对应的Mapper: public List
以上是學習mybatis動態sql用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!