首頁>技術>

MyBatis的動態SQL是基於OGNL表示式的,它可以幫助我們方便的在SQL語句中實現某些邏輯。

一、if標籤

此時如果CNAINDCLABASINFID為null,此語句很可能報錯或查詢結果為空。此時我們使用if動態sql語句先進行判斷,如果值為null或等於空字串,我們就不進行此條件的判斷,增加靈活性。

使用if+set標籤修改後,如果某項為null則不進行更新,而是保持資料庫原值。如下示例:

<update id="editRateAnalysTask" parameterType="RateAnalystScale" >UPDATE STUDENT_TBL<set>   <if test="studentName != null and studentName != '' ">      STUDENT_TBL.STUDENT_NAME = #{studentName},   </if>   <if test="studentSex != null and studentSex != '' ">      STUDENT_TBL.STUDENT_SEX = #{studentSex},   </if>   <if test="studentBirthday != null ">      STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},   </if>   <if test="studentPhoto != null ">      STUDENT_TBL.STUDENT_PHOTO = #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},   </if>   <if test="classId != '' ">      STUDENT_TBL.CLASS_ID = #{classId}   </if>   <if test="placeId != '' ">      STUDENT_TBL.PLACE_ID = #{placeId}   </if></set>WHERE STUDENT_TBL.STUDENT_ID = #{studentId};</update>
四、choose (when,otherwise)

有時候我們並不想應用所有的條件,而只是想從多個選項中選擇一個。而使用if標籤時,只要test中的表示式為true,就會執行if標籤中的條件。MyBatis提供了choose 元素。if標籤是與(and)的關係,而choose標籤是或(or)的關係。

choose標籤是按順序判斷其內部when標籤中的test條件是否成立,如果有一個成立,則choose結束。當choose中所有when的條件都不滿則時,則執行otherwise中的sql。類似於Java 的switch 語句,choose為switch,when為case,otherwise則為default。

例如下面例子,同樣把所有可以限制的條件都寫上,方便使用。choose會從上到下選擇一個when標籤的test為true的sql執行。安全考慮,我們使用where將choose包起來,放置關鍵字多於錯誤。

<select id="">   SELECT ST.STUDENT_ID,   ST.STUDENT_NAME,   ST.STUDENT_SEX,   ST.STUDENT_BIRTHDAY,   ST.STUDENT_PHOTO,   ST.CLASS_ID,   ST.PLACE_ID   FROM STUDENT_TBL ST   <where>      <choose>         <when test="studentName !=null ">            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')         </when >         <when test="studentSex != null and studentSex != '' ">            AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}         </when >         <when test="studentBirthday != null ">            AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}         </when >         <when test="classId != null and classId!= '' ">            AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}         </when >         <when test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' ">            AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}         </when >         <when test="placeId != null and placeId != '' ">            AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}         </when >         <when test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">            AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}         </when >         <when test="studentId != null and studentId != '' ">            AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}         </when >         <otherwise>         </otherwise>      </choose>   </where></select>
五、trim標籤

trim元素的主要功能是可以在自己包含的內容前加上某些字首,也可以在其後加上某些字尾,與之對應的屬性是prefix和suffix;可以把包含內容的首部某些內容覆蓋,即忽略,也可以把尾部的某些內容覆蓋,對應的屬性是prefixOverrides和suffixOverrides。正因為trim有這樣的功能,所以我們也可以非常簡單的利用trim來代替where/set標籤的功能,示例程式碼如下:

trim代替where標籤

select * from user   <trim prefix="WHERE" prefixoverride="AND |OR">    <if test="name != null and name.length()>0"> AND name=#{name}</if>    <if test="gender != null and gender.length()>0"> AND gender=#{gender}</if>  </trim>

假如說name和gender的值都不為null的話列印的SQL為:select * from user where name = 'xx' and gender = 'xx'

在紅色標記的地方是不存在第一個and的,上面兩個屬性的意思如下:

prefix:字首

prefixoverride:去掉第一個and或者是or

trim代替set標籤

update user  <trim prefix="set" suffixoverride="," suffix=" where id = #{id} ">    <if test="name != null and name.length()>0"> name=#{name} , </if>    <if test="gender != null and gender.length()>0"> gender=#{gender} ,  </if>  </trim>

假如說name和gender的值都不為null的話列印的SQL為:update user set name='xx' , gender='xx' where id='x'

在紅色標記的地方不存在逗號,而且自動加了一個set字首和where字尾,上面三個屬性的意義如下,其中prefix意義如上:

suffixoverride:去掉最後一個逗號(也可以是其他的標記,就像是上面字首中的and一樣)

suffix:字尾

六、foreach 標籤

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裡面的key1. 單引數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<Blog> dynamicForeachTest(List<Integer> ids);
2. 單引數array陣列的型別:
<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,對應的Mapper程式碼:

public List<Blog> dynamicForeach2Test(int[] ids);
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>

上述collection的值為ids,是傳入的引數Map的key,對應的Mapper程式碼:

public List<Blog> dynamicForeach3Test(Map<String, Object> params);

15
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 一文徹底弄懂C++開源協程庫libco——原理及應用