Mybatis-動態SQL- if (判斷元素) where, trim, set foreach bind

Mybatis一項強大的功能就是動態SQL,你可以使用動態SQL爲SQL語句帶上一些邏輯,免除使用JDBC時拼裝SQL的痛苦,下面我們來看一些最常見的應用。

if (判斷元素)

我們在代碼中時常使用if語句來做判斷,而在Mybatis裏,也可以使用if元素,下面我們通過實例來看一個簡單的用法:

<select id="findProductList" parameterType="com.shuqing28.pojo.Products"
        resultType="com.shuqing28.pojo.Products">
    SELECT * FROM products
    WHERE 1=1
    <if test="prodName!=null and prodName!=''">
            AND prod_name like '%${prodName}%'
    </if>
</select>

這裏我們使用一個if語句來探測prodName是否爲空,如果不爲空就加上prod_name的模糊匹配,如果參數爲空就不構造這個條件。在這裏我們看到有個WHERE 1=1其實這裏是爲了防止後面條件一旦爲真,那麼不加上WHERE 1=1的話,查詢語句就變成了SELECT * FROM products AND prod_name like '%${prodName}%' ,直接接上了AND,有問題了。

其實還有幾種方法可以讓我們不使用WHERE 1=1

where, trim, set

針對上面的 WHERE 1=1我們可以使用WHERE元素替代:

<select id="findProductList" parameterType="com.shuqing28.pojo.Products"
        resultType="com.shuqing28.pojo.Products">
    SELECT * FROM products
    <where>
    <if test="prodName!=null and prodName!=''">
            AND prod_name like '%${prodName}%'
    </if>
    </where>
</select>

where元素裏面的if爲真時,它纔會把WHERE子句加進去,而且會自動調整AND是否存在。

也可以使用trim來調整格式:

<select id="findProductList" parameterType="com.shuqing28.pojo.Products"
        resultType="com.shuqing28.pojo.Products">
    SELECT * FROM products
    <trim prefix="WHERE" prefixOverrides="AND">
    <if test="prodName!=null and prodName!=''">
            AND prod_name like '%${prodName}%'
    </if>
    </trim>
</select>

在這裏prefix代表前綴,prefixoverride則會去掉第一個AND,所以最後的效果和where元素是一樣的。

而set元素則是應用於更新,加入我們要更新某個字段:

<update id="updateProduct" parameterType="com.shuqing28.pojo.Products">
    UPDATE products
    <set>
    <if test="prodName!=null and prodName!=''">
            AND prod_name like '%${prodName}%'
    </if>
    </set>
    WHERE prod_id=#{prodId}
</update>

這裏用set包裹,也就是如果if元素判斷爲真,就會自動添加SET子句

UPDATE products SET prod_name like '%${prodName}% WHERE prod_id=#{prodId}

當然也可以使用trim元素:

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

只要把前綴換成SET,suffixOverride則會自動把最後的不需要的,去掉,當然set自帶去最後逗號的功能。

foreach

顯然foreach是一個循環語句,它的作用就是遍歷集合,如果傳入的是一個List、Set接口的集合,那麼它就可以大展身手了。假如有以下的查詢:

SELECT * FROM products WHERE prod_id IN ("ANV01", "ANV02", "ANV03");

那麼我們可以把3個參數封裝到一個List中,然後用foreach語句遍歷取出:

<select id="findProductListByProdId" parameterType="java.util.List"
        resultType="com.shuqing28.pojo.Products">
    SELECT * FROM products
    WHERE prod_id IN
    <foreach item="prod_id" index="index" collection="list" open="(" separator="," close=")">
            #{prod_id}
    </foreach>
</select>

再看看使用時是怎麼操作的:

@Test
public void findProductListByProdId(){
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
        OrdersDao ordersDao = sqlSession.getMapper(OrdersDao.class);
        List<String> prodList = new ArrayList<String>();
        prodList.add("ANV01");
        prodList.add("ANV02");
        prodList.add("ANV03");
        List<Products> productList = ordersDao.findProductListByProdId(prodList);
        System.out.println(productList);
    } finally {
        sqlSession.close();
    }
}

構造出查詢參數,直接傳入list即可。

bind

其它的動態SQL參數包括前面一直包含的test,用於在條件判斷元素中測試真假,還有個bind元素,用於定義一個上下文變量,比如我們第一個例子中的%${prodName}%,我們也可以用bind事先定義好:

<select id="findProductList" parameterType="com.shuqing28.pojo.Products"
        resultType="com.shuqing28.pojo.Products">
        <bind name="pattern" value="'%' + _parameter + '%'"/>
    SELECT * FROM products
    WHERE 1=1
    <if test="prodName!=null and prodName!=''">
            AND prod_name like #{pattern}'
    </if>
</select>

上例中我們預先定義好pattern,使用時就可以直接拿來用了,對於多處使用的變量適合這樣操作,這裏的_parameter代表傳入的參數,它和通配符結合後,賦給了pattern

關於動態SQL,常用的元素也就這些了。


作者:卡巴拉的樹
鏈接:https://juejin.im/post/5a8171855188257a856f4034
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
發佈了30 篇原創文章 · 獲贊 13 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章