日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mybatis入门(四)之动态SQL

發布時間:2023/12/3 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mybatis入门(四)之动态SQL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自??mybatis 動態SQL

動態 SQL

MyBatis 的強大特性之一便是它的動態 SQL。如果你有使用 JDBC 或其它類似框架的經驗,你就能體會到根據不同條件拼接 SQL 語句的痛苦。例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最后一個列名的逗號。利用動態 SQL 這一特性可以徹底擺脫這種痛苦。

雖然在以前使用動態 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射語句中的強大的動態 SQL 語言得以改進這種情形。

動態 SQL 元素和 JSTL 或基于類似 XML 的文本處理器相似。在 MyBatis 之前的版本中,有很多元素需要花時間了解。MyBatis 3 大大精簡了元素種類,現在只需學習原來一半的元素便可。MyBatis 采用功能強大的基于 OGNL 的表達式來淘汰其它大部分元素。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

if? ?

動態 SQL 通常要做的事情是根據條件包含 where 子句的一部分。比如:

<select id="findActiveBlogWithTitleLike"resultType="Blog">SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null">AND title like #{title}</if> </select>

? ? ? ?這條語句提供了一種可選的查找文本功能。如果沒有傳入“title”,那么所有處于“ACTIVE”狀態的BLOG都會返回;反之若傳入了“title”,那么就會對“title”一列進行模糊查找并返回 BLOG 結果(細心的讀者可能會發現,“title”參數值是可以包含一些掩碼或通配符的)。? ? ? ?

如果希望通過“title”和“author”兩個參數進行可選搜索該怎么辦呢?首先,改變語句的名稱讓它更具實際意義;然后只要加入另一個條件即可。

<select id="findActiveBlogLike"resultType="Blog">SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null">AND title like #{title}</if><if test="author != null and author.name != null">AND author_name like #{author.name}</if> </select>

choose, when, otherwise? ? ?

有時我們不想應用到所有的條件語句,而只想從中擇其一項。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。? ?

還是上面的例子,但是這次變為提供了“title”就按“title”查找,提供了“author”就按“author”查找的情形,若兩者都沒有提供,就返回所有符合條件的 BLOG(實際情況可能是由管理員按一定策略選出 BLOG 列表,而不是返回大量無意義的隨機結果)。

<select id="findActiveBlogLike"resultType="Blog">SELECT * FROM BLOG WHERE state = ‘ACTIVE’<choose><when test="title != null">AND title like #{title}</when><when test="author != null and author.name != null">AND author_name like #{author.name}</when><otherwise>AND featured = 1</otherwise></choose> </select>

trim, where, set

前面幾個例子已經合宜地解決了一個臭名昭著的動態 SQL 問題。現在回到“if”示例,這次我們將“ACTIVE = 1”也設置成動態的條件,看看會發生什么。

<select id="findActiveBlogLike"resultType="Blog">SELECT * FROM BLOG WHERE <if test="state != null">state = #{state}</if> <if test="title != null">AND title like #{title}</if><if test="author != null and author.name != null">AND author_name like #{author.name}</if> </select>

如果這些條件沒有一個能匹配上會發生什么?最終這條 SQL 會變成這樣:

SELECT * FROM BLOG WHERE

這會導致查詢失敗。如果僅僅第二個條件匹配又會怎樣?這條 SQL 最終會是這樣:

SELECT * FROM BLOG WHERE AND title like ‘someTitle’

這個查詢也會失敗。這個問題不能簡單地用條件句式來解決,如果你也曾經被迫這樣寫過,那么你很可能從此以后都不會再寫出這種語句了。 ? ? ?

MyBatis 有一個簡單的處理,這在 90% 的情況下都會有用。而在不能使用的地方,你可以自定義處理方式來令其正常工作。一處簡單的修改就能達到目的:

<select id="findActiveBlogLike"resultType="Blog">SELECT * FROM BLOG <where> <if test="state != null">state = #{state}</if> <if test="title != null">AND title like #{title}</if><if test="author != null and author.name != null">AND author_name like #{author.name}</if></where> </select>

where?元素只會在至少有一個子元素的條件返回 SQL 子句的情況下才去插入“WHERE”子句。而且,若語句的開頭為“AND”或“OR”,where?元素也會將它們去除。

如果?where?元素沒有按正常套路出牌,我們可以通過自定義 trim 元素來定制?where?元素的功能。比如,和?where?元素等價的自定義 trim 元素為:

<trim prefix="WHERE" prefixOverrides="AND |OR ">... </trim>

prefixOverrides?屬性會忽略通過管道分隔的文本序列(注意此例中的空格也是必要的)。它的作用是移除所有指定在?prefixOverrides?屬性中的內容,并且插入?prefix?屬性中指定的內容。

類似的用于動態更新語句的解決方案叫做?set。set?元素可以用于動態包含需要更新的列,而舍去其它的。比如:

<update id="updateAuthorIfNecessary">update Author<set><if test="username != null">username=#{username},</if><if test="password != null">password=#{password},</if><if test="email != null">email=#{email},</if><if test="bio != null">bio=#{bio}</if></set>where id=#{id} </update>

這里,set?元素會動態前置 SET 關鍵字,同時也會刪掉無關的逗號,因為用了條件語句之后很可能就會在生成的 SQL 語句的后面留下這些逗號。(譯者注:因為用的是“if”元素,若最后一個“if”沒有匹配上而前面的匹配上,SQL 語句的最后就會有一個逗號遺留)

若你對?set?元素等價的自定義 trim 元素的代碼感興趣,那這就是它的真面目:

<trim prefix="SET" suffixOverrides=",">... </trim> 注意這里我們刪去的是后綴值,同時添加了前綴值。

foreach

動態 SQL 的另外一個常用的操作需求是對一個集合進行遍歷,通常是在構建 IN 條件語句的時候。比如:

<select id="selectPostIn" resultType="domain.blog.Post">SELECT *FROM POST PWHERE ID in<foreach item="item" index="index" collection="list"open="(" separator="," close=")">#{item}</foreach> </select>

foreach?元素的功能非常強大,它允許你指定一個集合,聲明可以在元素體內使用的集合項(item)和索引(index)變量。它也允許你指定開頭與結尾的字符串以及在迭代結果之間放置分隔符。這個元素是很智能的,因此它不會偶然地附加多余的分隔符。

注意?你可以將任何可迭代對象(如 List、Set 等)、Map 對象或者數組對象傳遞給?foreach?作為集合參數。當使用可迭代對象或者數組時,index 是當前迭代的次數,item 的值是本次迭代獲取的元素。當使用 Map 對象(或者 Map.Entry 對象的集合)時,index 是鍵,item 是值。

到此我們已經完成了涉及 XML 配置文件和 XML 映射文件的討論。下一章將詳細探討 Java API,這樣就能提高已創建的映射文件的利用效率。

bind

bind?元素可以從 OGNL 表達式中創建一個變量并將其綁定到上下文。比如:

<select id="selectBlogsLike" resultType="Blog"><bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />SELECT * FROM BLOGWHERE title LIKE #{pattern} </select>

? ? ?

多數據庫支持

一個配置了“_databaseId”變量的 databaseIdProvider 可用于動態代碼中,這樣就可以根據不同的數據庫廠商構建特定的語句。比如下面的例子:

<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>

動態 SQL 中的可插拔腳本語言? ?

MyBatis 從 3.2 開始支持可插拔腳本語言,這允許你插入一種腳本語言驅動,并基于這種語言來編寫動態 SQL 查詢語句。

可以通過實現以下接口來插入一種語言:

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); } 一旦設定了自定義語言驅動,你就可以在 mybatis-config.xml 文件中將它設置為默認語言: <typeAliases><typeAlias type="org.sample.MyLanguageDriver" alias="myLanguage"/> </typeAliases> <settings><setting name="defaultScriptingLanguage" value="myLanguage"/> </settings>

除了設置默認語言,你也可以針對特殊的語句指定特定語言,可以通過如下的?lang?屬性來完成:

<select id="selectBlog" lang="myLanguage">SELECT * FROM BLOG </select>

或者,如果你使用的是映射器接口類,在抽象方法上加上?@Lang?注解即可:

public interface Mapper {@Lang(MyLanguageDriver.class)@Select("SELECT * FROM BLOG")List<Blog> selectBlog(); }

注意?可以將 Apache Velocity 作為動態語言來使用,更多細節請參考 MyBatis-Velocity 項目。

你前面看到的所有 xml 標簽都是由默認 MyBatis 語言提供的,而它由別名為?xml?的語言驅動器?org.apache.ibatis.scripting.xmltags.XmlLanguageDriver?所提供。

總結

以上是生活随笔為你收集整理的mybatis入门(四)之动态SQL的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。