mybatis 動態sql語句

mybatis動態sql語句主要有以下幾類:
1、if語句(簡單的條件判斷)
2、choose(when,otherwise),相當於java中的switch
3、trim(對包含的內容加上prefix、suffix,前綴、後綴)
4、where(主要用來簡化sql語句中where條件判斷,能智能處理and or ,不必擔心多餘導致語法錯誤)
5、set(主要用於更新時,能只能處理”,”,不必擔心”,”多餘導致語法錯誤)
6、foreach(在使用in條件查詢時)

1、mybatis if語句處理

<select id="dynamicIfTest" parameterType="Article" resultType="Article">
    select * from t_article where 1=1
    <if test="title != null and title != ''">
        and title = #{title}
    </if>
    <if test="content != null and content != ''">
        and content = #{content}
    </if>
</select>

該條語句只要你提供了title參數,就要滿足title=#{title}條件,同樣如果你提供了content參數,也要滿足content=#{content}條件,之後就是返回滿足這些條件的所有的Article對象。

2、mybatis choose(when,otherwise)語句處理,該語句相當於java中的switch。

<select id="dynamicChooseTest" parameterType="Article" resultType="Article">
    select * from t_article where 1=1
    <choose>
        <when test="title != null and title != ''">
            and title = #{title}
        </when>
        <when test="content != null and content != ''">
            and content = #{content}
        </when>
        <otherwise>
            and id = #{id}
        </otherwise>
    /choose>
</select>

when元素表示當有元素滿足條件時,即輸出其中內容,並且會跳出choose,因此所有when和otherwise中只會有一個輸出,當所有when的條件都不滿足時就會輸出otherwise中的內容。


3、trim(對包含的內容加上prefix、suffix,前綴、後綴)
在此,舉兩個例子對此進行解釋:
1)添加where前綴

<select id="dynamicTrimWhereTest" parameterType="Article" resultType="Article">
    select * from t_article 
    <trim prefix="where" prefixOverrides="and|or"> 
        <if test="title != null and title != ''">
            title = #{title}
        </if>
        <if test="content != null and content != ''">
            and content = #{content}
        </if>
    </trim>
</select>

最終生成的sql語句(title爲null,content有值情況):select * from t_article where content = ?。
trim標籤會和where標籤一樣自動識別和去掉不用的add 或 or.

2)添加set前綴

<update id="dynamicTrimSetTest" parameterType="Article" >
       update t_article 
       <trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
            <if test="title != null and title != ''">
                title = #{title},
            </if>
            <if test="content != null and content != ''">
                content = #{content},
            </if>
        </trim>
</update>

生成的sql語句:update t_article set title=?,content=? where id=?。
以上就是trim的兩種主要用法通過prefix和suffix給trim標籤中的內容添加前綴或者後綴,並且自動識別和去掉prefixOverrides和suffixOverrides指定的值。


4、where(主要用來簡化sql語句中where條件判斷,能智能處理and or ,不必擔心多餘導致語法錯誤)
當不使用where標籤時:

<select id="dynamicWhereTest" parameterType="Article" resultType="Article">
      select * from t_article where 
      <if test="title != null and title != ''">
          title = #{title}
      </if>
      <if test="content != null and content != ''">
          and content = #{content}
      </if>
</select>

上面生成的sql語句如果當title爲null,content不爲null時,生成的sql語句:
select * from t_article where and content = ?。這是一條錯誤的sql語句,爲了避免該問題的出現,因此我們需要使用where標籤,where標籤會自動識別和去掉and或or:

<select id="dynamicWhereTest" parameterType="Article" resultType="Article">
      select * from t_article
      <where>
          <if test="title != null and title != ''">
               title = #{title}
          </if>
          <if test="content != null and content != ''">
               and content = #{content}
          </if>
      </where>
</select>


5、set(主要用於更新時,能只能處理”,”,不必擔心”,”多餘導致語法錯誤)

 <update id="dynamicSetTest" parameterType="Article">
         update t_article 
         <set>
             <if test="title != null and title != ''">
                title = #{title},
             </if>
             <if test="content != null and content != ''">
                content = #{content},
             </if>
         </set>
         where id = #{id}
</update>

set標籤主要用於更新操作,其功能和where差不多,set標籤能自動識別和去掉多餘的”,”。


6、foreach(主要用於在使用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。

單參數List類型:

<select id="dynamicForeachListTest" resultType="Article">
        select * from t_article where id in 
        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
</select>

對應的Mapper方法

public List<Article> dynamicForeachListTest(List<Integer> ids);

單參數Array類型:

<select id="dynamicForeachArrayList" resultType="Article">
       select * from t_article where id in
       <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
             #{item}
       </foreach>
</select> 

對應的mapper方法

public List<Article> dynamicForeachArrayList(int[] ids);

多個參數Map類型

 <select id="dynamicForeachMapList" resultType="Article" >
        select * from t_article where title like "%"#{title}"%" and id in
        <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
             #{item}
        </foreach>

</select>

對應Mapper方法:

public List<Article> dynamicForeachMapList(Map<String,Object> map);

測試代碼:

public void testDynamicForeachMap(){
        SqlSession session = sqlSessionFactory.openSession();

        try {
            UserMapper userMapper = session.getMapper(UserMapper.class);
            Map<String,Object> map = new HashMap<>();
            map.put("title", "標題");
            List<Integer> ids = new ArrayList<>();
            ids.add(1);
            ids.add(3);
            map.put("ids", ids);

            List<Article> articles = userMapper.dynamicForeachMapList(map);
            for (Article article : articles) {
                System.out.println(article);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(session != null){
                session.close();
            }
        }
    }
發佈了57 篇原創文章 · 獲贊 12 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章