MyBatis經常使用SQL語句整理筆記

最近使用Mybatis做爲持久層框架,天然/動態sql寫得也比較多了,最多見的就是在查詢語句中使用if標籤來動態地改變過濾條件。
Mybatis強大特性之一就是它的動態sql,免除了拼接sql帶來的各類麻煩。
在項目開發過程當中,常見的和不常見的問題都有碰到過,因此在這總結一下。
if
choose(when,otherwise)
trim(where,set)
foreach

1.一般用於多條件組合查詢
<select id="productId" parameterType="Product" resultMap="getProduct">
    SELECT * FROM PRODUCT t WHERE (1=1)
    <if test="Product.productId!=null">
        AND t.PRODUCT_ID = #{Product.productId}
    </if>
    <if test="Product.productName!=null">
        AND t.PRODUCT_NAME like '%#{Product.productName}%'
    </if>
    <if test="Product.inStock!=null">
        AND t.PRODUCT.INSTOCK = 0
    </if>
    ORDER BY SEQUENCE_NO
</select>

2.這適用於數據庫有默認值的時候能夠不讓插入空值

<insert id="addCategory" parameterType="Category">
    INSERT INTO CATEGORY(
    <if test="categoryName!=null and categoryName!='' ">
        CATEGORY_NAME
    </if>
    <if test="categoryId!=null and categoryId!='' ">
        CATEGORY_ID
    </if>
    ADD_TIME)
    VALUES(
        <if test="categoryName!=null and categoryName!='' ">
            #{categoryName, jdbcType=VARCHAR}
        </if>
        <if test="categoryId!=null and categoryId!='' ">
            #{categoryId, jdbcType=NUMERIC}
        </if>
        currentTimeStamp
    )
</insert>

3.這條動態地修改語句用得很是多
,是由於不少時候咱們在作修改操做時並不肯定到底要修改哪些字段(哪些屬性),可能有的須要保存原值不變.

這時候就能夠作動態的sql,你新建一個對象後,將須要修改的字段附上新值,這樣不用修改的屬性在這個對象上表現的是null,調用這個動態的sql時即可以完成部分修改。
<update id="updateCategory" parameterType="Category">
    update CATEGORY t SET
    <if test="categoryName!=null">
        t.CATEGORY_NAME = #{categoryName, jdbcType=VARCHAR},
    </if>
    <if test="updateUser!=null">
        t.UPDATE_USER = #{updateUser, jdbcType=VARCHAR},
    </if>
    t.UPDATE_TIME = currentTimeStamp
    WHERE t.CATEGORY_ID = #{categoryId, jdbcType=NUMERIC}
</update>

4.choose,when,otherwise
適用場景:咱們不想用到全部的條件語句,而只想從中擇其一二。
針對這種狀況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。
(我感受它有點像提供多種條件規則時,而這些規則又能夠綜合寫在一塊兒時)
<select id="findInStockLike" resultType="Product">
    SELECT * FROM PRODUCT WHERE STATE = 'INSTOCK'
    <choose>
        <when>
            AND TITLE LIKE #{title}
        </when>
        <when>
            AND BRAND_NAME LIKE #{brand.name}
        </when>
        <otherwise>
            AND INMARKETING = 0
        </otherwise>
    </choose>
</select>

5.where, set, trim
爲了不當if動態條件都不成立時,或者第一個條件不成立第二個條件成立時出現
諸如"select * from TableA where"
或者"select * from TableA and where"病態sql,
咱們可使用where, set, trim標籤來解決。
5.1)where
<select id="findInStockProductLike" resultType="Product">
    SELECT * FROM PRODUCT
    <when>
        <if    test="state!=null">
            STATE = #{state}
        </if>
        <if test="title!=null">
            AND TITLE LIKE #{title}
        </if>
        <if test="brand!=null and brand.name!=null">
            AND BRAND_NAME LIKE #{brand.name}
        </if>
    </when>
</select>
在實際應用中,我一般是不寫where標籤,而在where關鍵字以後加上1=1的條件。即無論有無動態條件,總能夠獲得完整的sql:select * from A where 1=1。。。
5.2)set
<update id="updateUserInfo">
    UPDATE USER
    <set>
        <if test="userName!=null">USER_NAME = #{userName}</if>
        <if test="userPsw!=null">USER_PSW = #{userPsw}</if>
        <if test="userEmail!=null">USER_EMAIL = #{userEmail}</if>
    </set>
    WHERE USER_ID = #{userId}
</update>

6.foreach

foreach有時候在項目中會遇到,並且不止一次,用的時候是須要動點腦子的。
一般用於篩選出在多個值組成的一個集合中或者排除多個值的場景.
說白了,也就是咱們以前寫sql時用到in、not in的時候:(集合是動態不肯定的,須要從前臺傳值過來)
<select id="selectProdcutNoInOrder" resultType="String">
    SELECT COUNT(0) FROM PRODUCT a LEFT JOIN ORDER_INFO b
    ON a.PRODUCT_ID = b.PRODUCT_ID
    WHERE a.STATUS in('1', '2', '3', '6')
    <if test="list.size()>0">
        AND b.PHONE_NUM IN
        <foreach item="phoneNumList" collection="list" open="(" separator="," close=")">
            #{phoneNumList.num}
        </foreach>
    </if>
</select>
foreach 元素的功能是很是強大的,它容許你指定一個集合,聲明能夠用在元素體內的集合項和索引變量。
它也容許你指定開閉匹配的字符串以及在迭代中間放置分隔符。
這個元素是很智能的,所以它不會偶然地附加多餘的分隔符。
注意,你能夠將一個 List 實例或者數組做爲參數對象傳給 MyBatis,當你這麼作的時候,MyBatis 會自動將它包裝在一個 Map 中並以名稱爲鍵。
List 實例將會以「list」做爲鍵,而數組實例的鍵將是「array」。
<select id="selectProductIn" resultType="com.dowik.dowikmall.Product">
    SELECT * FROM PRODUCT p WHERE PRODUCT_ID IN
    <foreach item="productIdList" index="index" collection="list" open="(" separetor="," close=")">
        #{productIdList}
    </foreach>
</select>
相關文章
相關標籤/搜索