溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MyBatis中XML映射文件中常見的標(biāo)簽介紹

發(fā)布時間:2021-07-28 17:06:22 來源:億速云 閱讀:261 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“MyBatis中XML映射文件中常見的標(biāo)簽介紹”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

SQL 映射文件只有很少的幾個頂級元素(按照應(yīng)被定義的順序列出):

  • cache – 對給定命名空間的緩存配置。

  • cache-ref – 對其他命名空間緩存配置的引用。

  • resultMap – 是最復(fù)雜也是最強(qiáng)大的元素,用來描述如何從數(shù)據(jù)庫結(jié)果集中來加載對象。

  • parameterMap – 已被廢棄!老式風(fēng)格的參數(shù)映射。更好的辦法是使用內(nèi)聯(lián)參數(shù),此元素可能在將來被移除。

  • sql – 可被其他語句引用的可重用語句塊。

  • insert – 映射插入語句

  • update – 映射更新語句

  • delete – 映射刪除語句

  • select – 映射查詢語句

select

<select id="selectPerson" parameterType="int" resultType="hashmap">
   SELECT * FROM PERSON WHERE ID = #{id}
 </select>

這個語句被稱作 selectPerson,接受一個 int(或 Integer)類型的參數(shù),并返回一個 HashMap 類型的對象,其中的鍵是列名,值便是結(jié)果行中的對應(yīng)值。

注意參數(shù)符號:#{id}

這就告訴 MyBatis 創(chuàng)建一個預(yù)處理語句(PreparedStatement)參數(shù),在 JDBC 中,這樣的一個參數(shù)在 SQL 中會由一個“?”來標(biāo)識,并被傳遞到一個新的預(yù)處理語句中,就像這樣:

// 近似的 JDBC 代碼,非 MyBatis 代碼...
 String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
 PreparedStatement ps = conn.prepareStatement(selectPerson);
 ps.setInt(1,id);
 <select
   id="selectPerson"
   parameterType="int"
   parameterMap="deprecated"
   resultType="hashmap"
   resultMap="personResultMap"
   flushCache="false"
   useCache="true"
   timeout="10"
   fetchSize="256"
   statementType="PREPARED"
   resultSetType="FORWARD_ONLY">
屬性描述
id在命名空間中唯一的標(biāo)識符,可以被用來引用這條語句。
parameterType將會傳入這條語句的參數(shù)類的完全限定名或別名。這個屬性是可選的,因為 MyBatis 可以通過類型處理器(TypeHandler) 推斷出具體傳入語句的參數(shù),默認(rèn)值為未設(shè)置(unset)。
parameterMap這是引用外部 parameterMap 的已經(jīng)被廢棄的方法。請使用內(nèi)聯(lián)參數(shù)映射和 parameterType 屬性。
resultType從這條語句中返回的期望類型的類的完全限定名或別名。 注意如果返回的是集合,那應(yīng)該設(shè)置為集合包含的類型,而不是集合本身??梢允褂?resultType 或 resultMap,但不能同時使用。
resultMap外部 resultMap 的命名引用。結(jié)果集的映射是 MyBatis 最強(qiáng)大的特性,如果你對其理解透徹,許多復(fù)雜映射的情形都能迎刃而解??梢允褂?resultMap 或 resultType,但不能同時使用。
flushCache將其設(shè)置為 true 后,只要語句被調(diào)用,都會導(dǎo)致本地緩存和二級緩存被清空,默認(rèn)值:false。
useCache將其設(shè)置為 true 后,將會導(dǎo)致本條語句的結(jié)果被二級緩存緩存起來,默認(rèn)值:對 select 元素為 true。
timeout這個設(shè)置是在拋出異常之前,驅(qū)動程序等待數(shù)據(jù)庫返回請求結(jié)果的秒數(shù)。默認(rèn)值為未設(shè)置(unset)(依賴驅(qū)動)。
fetchSize這是一個給驅(qū)動的提示,嘗試讓驅(qū)動程序每次批量返回的結(jié)果行數(shù)和這個設(shè)置值相等。 默認(rèn)值為未設(shè)置(unset)(依賴驅(qū)動)。
statementTypeSTATEMENT,PREPARED 或 CALLABLE 中的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。
resultSetTypeFORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等價于 unset) 中的一個,默認(rèn)值為 unset (依賴驅(qū)動)。
databaseId如果配置了數(shù)據(jù)庫廠商標(biāo)識(databaseIdProvider),MyBatis 會加載所有的不帶 databaseId 或匹配當(dāng)前 databaseId 的語句;如果帶或者不帶的語句都有,則不帶的會被忽略。
resultOrdered這個設(shè)置僅針對嵌套結(jié)果 select 語句適用:如果為 true,就是假設(shè)包含了嵌套結(jié)果集或是分組,這樣的話當(dāng)返回一個主結(jié)果行的時候,就不會發(fā)生有對前面結(jié)果集的引用的情況。 這就使得在獲取嵌套的結(jié)果集的時候不至于導(dǎo)致內(nèi)存不夠用。默認(rèn)值:false。
resultSets這個設(shè)置僅對多結(jié)果集的情況適用。它將列出語句執(zhí)行后返回的結(jié)果集并給每個結(jié)果集一個名稱,名稱是逗號分隔的。

insert, update 和 delete

數(shù)據(jù)變更語句 insert,update 和 delete 的實現(xiàn)非常接近:

<insert
   id="insertAuthor"
   parameterType="domain.blog.Author"
   flushCache="true"
   statementType="PREPARED"
   keyProperty=""
   keyColumn=""
   useGeneratedKeys=""
   timeout="20">
 
 <update
   id="updateAuthor"
   parameterType="domain.blog.Author"
   flushCache="true"
   statementType="PREPARED"
   timeout="20">
 
 <delete
   id="deleteAuthor"
   parameterType="domain.blog.Author"
   flushCache="true"
   statementType="PREPARED"
   timeout="20">
屬性描述
id命名空間中的唯一標(biāo)識符,可被用來代表這條語句。
parameterType將要傳入語句的參數(shù)的完全限定類名或別名。這個屬性是可選的,因為 MyBatis 可以通過類型處理器推斷出具體傳入語句的參數(shù),默認(rèn)值為未設(shè)置(unset)。
parameterMap這是引用外部 parameterMap 的已經(jīng)被廢棄的方法。請使用內(nèi)聯(lián)參數(shù)映射和 parameterType 屬性。
flushCache將其設(shè)置為 true 后,只要語句被調(diào)用,都會導(dǎo)致本地緩存和二級緩存被清空,默認(rèn)值:true(對于 insert、update 和 delete 語句)。
timeout這個設(shè)置是在拋出異常之前,驅(qū)動程序等待數(shù)據(jù)庫返回請求結(jié)果的秒數(shù)。默認(rèn)值為未設(shè)置(unset)(依賴驅(qū)動)。
statementTypeSTATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。
useGeneratedKeys(僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數(shù)據(jù)庫內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系數(shù)據(jù)庫管理系統(tǒng)的自動遞增字段),默認(rèn)值:false。
keyProperty(僅對 insert 和 update 有用)唯一標(biāo)記一個屬性,MyBatis 會通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設(shè)置它的鍵值,默認(rèn)值:未設(shè)置(unset)。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。
keyColumn(僅對 insert 和 update 有用)通過生成的鍵值設(shè)置表中的列名,這個設(shè)置僅在某些數(shù)據(jù)庫(像 PostgreSQL)是必須的,當(dāng)主鍵列不是表中的第一列的時候需要設(shè)置。如果希望使用多個生成的列,也可以設(shè)置為逗號分隔的屬性名稱列表。
databaseId如果配置了數(shù)據(jù)庫廠商標(biāo)識(databaseIdProvider),MyBatis 會加載所有的不帶 databaseId 或匹配當(dāng)前 databaseId 的語句;如果帶或者不帶的語句都有,則不帶的會被忽略。

生成主鍵

 <selectKey
   keyProperty="id"
   resultType="int"
   order="BEFORE"
   statementType="PREPARED">
屬性描述
keyPropertyselectKey 語句結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。
keyColumn匹配屬性的返回結(jié)果集中的列名稱。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。
resultType結(jié)果的類型。MyBatis 通常可以推斷出來,但是為了更加精確,寫上也不會有什么問題。MyBatis 允許將任何簡單類型用作主鍵的類型,包括字符串。如果希望作用于多個生成的列,則可以使用一個包含期望屬性的 Object 或一個 Map。
order這可以被設(shè)置為 BEFORE 或 AFTER。如果設(shè)置為 BEFORE,那么它會首先生成主鍵,設(shè)置 keyProperty 然后執(zhí)行插入語句。如果設(shè)置為 AFTER,那么先執(zhí)行插入語句,然后是 selectKey 中的語句 - 這和 Oracle 數(shù)據(jù)庫的行為相似,在插入語句內(nèi)部可能有嵌入索引調(diào)用。
statementType與前面相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 語句的映射類型,分別代表 PreparedStatement 和 CallableStatement 類型。
 <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
   SELECT LAST_INSERT_ID() AS id
 </selectKey>

sql

這個元素可以被用來定義可重用的 SQL 代碼段,這些 SQL 代碼可以被包含在其他語句中。它可以(在加載的時候)被靜態(tài)地設(shè)置參數(shù)。 在不同的包含語句中可以設(shè)置不同的值到參數(shù)占位符上。比如:

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
 <select id="selectUsers" resultType="map">
   select
     <include refid="userColumns"><property name="alias" value="t1"/></include>,
     <include refid="userColumns"><property name="alias" value="t2"/></include>
   from some_table t1
     cross join some_table t2
 </select>

結(jié)果映射

resultMap 元素是 MyBatis 中最重要最強(qiáng)大的元素,在一些情形下允許你進(jìn)行一些 JDBC 不支持的操作。實際上,在為一些比如連接的復(fù)雜語句編寫映射代碼的時候,一份 resultMap 能夠代替實現(xiàn)同等功能的長達(dá)數(shù)千行的代碼。ResultMap 的設(shè)計思想是,對于簡單的語句根本不需要配置顯式的結(jié)果映射,而對于復(fù)雜一點的語句只需要描述它們的關(guān)系就行了。

在JavaBean中定義一個有 3 個屬性:id,username 和 hashedPassword的類,然后在mapper.xml中,這些屬性會對應(yīng)到 select 語句中的列名,這樣的一個 JavaBean 可以被映射到 ResultSet,就像映射到 HashMap 一樣簡單。

<select id="selectUsers" resultType="com.someapp.model.User">
   select id, username, hashedPassword
   from some_table
   where id = #{id}
 </select>

像第三中的第三個例子,也可以定義外部resultMap,這也是解決列名不匹配的另外一種方式。

 <resultMap id="userResultMap" type="User">
   <id property="id" column="user_id" />
   <result property="username" column="user_name"/>
   <result property="password" column="hashed_password"/>
 </resultMap>
 
 <select id="selectUsers" resultMap="userResultMap">
   select user_id, user_name, hashed_password
   from some_table
   where id = #{id}
 </select>

結(jié)果映射(resultMap)

  • constructor-用于在實例化類時,注入結(jié)果到構(gòu)造方法中

  • idArg - ID 參數(shù);標(biāo)記出作為 ID 的結(jié)果可以幫助提高整體性能

  • arg - 將被注入到構(gòu)造方法的一個普通結(jié)果

  • id – 一個 ID 結(jié)果;標(biāo)記出作為 ID 的結(jié)果可以幫助提高整體性能

  • result – 注入到字段或 JavaBean 屬性的普通結(jié)果

  • association– 一個復(fù)雜類型的關(guān)聯(lián);許多結(jié)果將包裝成這種類型

  • 嵌套結(jié)果映射 – 關(guān)聯(lián)本身可以是一個 resultMap 元素,或者從別處引用一個

  • collection– 一個復(fù)雜類型的集合

  • 嵌套結(jié)果映射 – 集合本身可以是一個 resultMap 元素,或者從別處引用一個

  • discriminator– 使用結(jié)果值來決定使用哪個resultMap

  • case– 基于某些值的結(jié)果映射

  • 嵌套結(jié)果映射 – case 本身可以是一個 resultMap 元素,因此可以具有相同的結(jié)構(gòu)和元素,或者從別處引用一個。


屬性描述
id當(dāng)前命名空間中的一個唯一標(biāo)識,用于標(biāo)識一個結(jié)果映射。
type類的完全限定名, 或者一個類型別名(關(guān)于內(nèi)置的類型別名,可以參考上面的表格)。
autoMapping如果設(shè)置這個屬性,MyBatis將會為本結(jié)果映射開啟或者關(guān)閉自動映射。 這個屬性會覆蓋全局的屬性 autoMappingBehavior。默認(rèn)值:未設(shè)置(unset)。

id & result

 <id property="id" column="post_id"/>
 <result property="subject" column="post_subject"/>

這些是結(jié)果映射最基本的內(nèi)容。id 和 result 元素都將一個列的值映射到一個簡單數(shù)據(jù)類型(String, int, double, Date 等)的屬性或字段。

這兩者之間的唯一不同是,id 元素表示的結(jié)果將是對象的標(biāo)識屬性,這會在比較對象實例時用到。 這樣可以提高整體的性能,尤其是進(jìn)行緩存和嵌套結(jié)果映射(也就是連接映射)的時候。

屬性描述
property映射到列結(jié)果的字段或?qū)傩浴H绻脕砥ヅ涞?JavaBean 存在給定名字的屬性,那么它將會被使用。否則 MyBatis 將會尋找給定名稱的字段。 無論是哪一種情形,你都可以使用通常的點式分隔形式進(jìn)行復(fù)雜屬性導(dǎo)航。 比如,你可以這樣映射一些簡單的東西:“username”,或者映射到一些復(fù)雜的東西上:“address.street.number”。
column數(shù)據(jù)庫中的列名,或者是列的別名。一般情況下,這和傳遞給 resultSet.getString(columnName) 方法的參數(shù)一樣。
javaType一個 Java 類的完全限定名,或一個類型別名(關(guān)于內(nèi)置的類型別名,可以參考上面的表格)。 如果你映射到一個 JavaBean,MyBatis 通??梢酝茢囝愋?。然而,如果你映射到的是 HashMap,那么你應(yīng)該明確地指定 javaType 來保證行為與期望的相一致。
jdbcTypeJDBC 類型,所支持的 JDBC 類型參見這個表格之后的“支持的 JDBC 類型”。 只需要在可能執(zhí)行插入、更新和刪除的且允許空值的列上指定 JDBC 類型。這是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 編程,你需要對可能存在空值的列指定這個類型。
typeHandler我們在前面討論過默認(rèn)的類型處理器。使用這個屬性,你可以覆蓋默認(rèn)的類型處理器。 這個屬性值是一個類型處理器實現(xiàn)類的完全限定名,或者是類型別名。

緩存

默認(rèn)情況下,只啟用了本地的會話緩存,它僅僅對一個會話中的數(shù)據(jù)進(jìn)行緩存。 要啟用全局的二級緩存,只需要在你的 SQL 映射文件中添加一行:<cache/>

基本上就是這樣。這個簡單語句的效果如下:

  • 映射語句文件中的所有 select 語句的結(jié)果將會被緩存。

  • 映射語句文件中的所有 insert、update 和 delete 語句會刷新緩存。

  • 緩存會使用最近最少使用算法(LRU, Least Recently Used)算法來清除不需要的緩存。

  • 緩存不會定時進(jìn)行刷新(也就是說,沒有刷新間隔)。

  • 緩存會保存列表或?qū)ο螅o論查詢方法返回哪種)的 1024 個引用。

  • 緩存會被視為讀/寫緩存,這意味著獲取到的對象并不是共享的,可以安全地被調(diào)用者修改,而不干擾其他調(diào)用者或線程所做的潛在修改。

提示 緩存只作用于 cache 標(biāo)簽所在的映射文件中的語句。如果你混合使用 Java API 和 XML 映射文件,在共用接口中的語句將不會被默認(rèn)緩存。你需要使用 @CacheNamespaceRef 注解指定緩存作用域。

這些屬性可以通過 cache 元素的屬性來修改。比如:

 <cache
   eviction="FIFO"
   flushInterval="60000"
   size="512"
   readOnly="true"/>

這個更高級的配置創(chuàng)建了一個 FIFO 緩存,每隔 60 秒刷新,最多可以存儲結(jié)果對象或列表的 512 個引用,而且返回的對象被認(rèn)為是只讀的,因此對它們進(jìn)行修改可能會在不同線程中的調(diào)用者產(chǎn)生沖突。

可用的清除策略有:

  • LRU – 最近最少使用:移除最長時間不被使用的對象。

  • FIFO – 先進(jìn)先出:按對象進(jìn)入緩存的順序來移除它們。

  • SOFT – 軟引用:基于垃圾回收器狀態(tài)和軟引用規(guī)則移除對象。

  • WEAK – 弱引用:更積極地基于垃圾收集器狀態(tài)和弱引用規(guī)則移除對象。

默認(rèn)的清除策略是 LRU。

flushInterval(刷新間隔)屬性可以被設(shè)置為任意的正整數(shù),設(shè)置的值應(yīng)該是一個以毫秒為單位的合理時間量。 默認(rèn)情況是不設(shè)置,也就是沒有刷新間隔,緩存僅僅會在調(diào)用語句時刷新。

size(引用數(shù)目)屬性可以被設(shè)置為任意正整數(shù),要注意欲緩存對象的大小和運(yùn)行環(huán)境中可用的內(nèi)存資源。默認(rèn)值是 1024。

readOnly(只讀)屬性可以被設(shè)置為 true 或 false。只讀的緩存會給所有調(diào)用者返回緩存對象的相同實例。 因此這些對象不能被修改。這就提供了可觀的性能提升。而可讀寫的緩存會(通過序列化)返回緩存對象的拷貝。 速度上會慢一些,但是更安全,因此默認(rèn)值是 false。

提示 二級緩存是事務(wù)性的。這意味著,當(dāng) SqlSession 完成并提交時,或是完成并回滾,但沒有執(zhí)行 flushCache=true 的 insert/delete/update 語句時,緩存會獲得更新。

使用自定義緩存

除了上述自定義緩存的方式,你也可以通過實現(xiàn)你自己的緩存,或為其他第三方緩存方案創(chuàng)建適配器,來完全覆蓋緩存行為。

 <cache type="com.domain.something.MyCustomCache"/>

例子:

type 屬性指定的類必須實現(xiàn) org.mybatis.cache.Cache 接口,且提供一個接受 String 參數(shù)作為 id 的構(gòu)造器。 這個接口是 MyBatis 框架中許多復(fù)雜的接口之一,但是行為卻非常簡單。

 public interface Cache {
   String getId();
   int getSize();
   void putObject(Object key, Object value);
   Object getObject(Object key);
   boolean hasKey(Object key);
   Object removeObject(Object key);
   void clear();
 }

動態(tài)SQL

  • Mybatis 動態(tài) SQL ,可以讓我們在 XML 映射文件內(nèi),以 XML 標(biāo)簽的形式編寫動態(tài) SQL ,完成邏輯判斷和動態(tài)拼接 SQL 的功能。

  • Mybatis 提供了 9 種動態(tài) SQL 標(biāo)簽:<if />、<choose />、<when />、<otherwise />、<trim />、<where />、<set />、<foreach />、<bind /> 。

  • 其執(zhí)行原理為,使用 OGNL 的表達(dá)式,從 SQL 參數(shù)對象中計算表達(dá)式的值,根據(jù)表達(dá)式的值動態(tài)拼接 SQL ,以此來完成動態(tài) SQL 的功能。

if

動態(tài) SQL 通常要做的事情是根據(jù)條件包含 where 子句的一部分。比如:

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

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

通過“title”和“author”兩個參數(shù)進(jìn)行可選搜索:

 <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

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

這次變?yōu)樘峁┝恕皌itle”就按“title”查找,提供了“author”就按“author”查找的情形,若兩者都沒有提供,就返回所有符合條件的 BLOG(實際情況可能是由管理員按一定策略選出 BLOG 列表,而不是返回大量無意義的隨機(jī)結(jié)果)。

 <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語句,導(dǎo)致無法查詢,如:SELECT * FROM BLOG WHERE

 <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 元素也會將它們?nèi)コ?/p>

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

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

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

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

 <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 元素會動態(tài)前置 SET 關(guān)鍵字,同時也會刪掉無關(guān)的逗號,因為用了條件語句之后很可能就會在生成的 SQL 語句的后面留下這些逗號。(譯者注:因為用的是“if”元素,若最后一個“if”沒有匹配上而前面的匹配上,SQL 語句的最后就會有一個逗號遺留)

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

 <trim prefix="SET" suffixOverrides=",">
   ...
 </trim>

注意這里我們刪去的是后綴值,同時添加了前綴值。

foreach

動態(tài) SQL 的另外一個常用的操作需求是對一個集合進(jìn)行遍歷,通常是在構(gòu)建 IN 條件語句的時候。比如:

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

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

注意

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

bind

bind 元素可以從 OGNL 表達(dá)式中創(chuàng)建一個變量并將其綁定到上下文。比如:

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

“MyBatis中XML映射文件中常見的標(biāo)簽介紹”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI