MyBatis - 常用標簽與動態Sql


一、MyBatis常用標簽

● 定義sql語句:select、insert、delete、update
● 配置JAVA對象屬性與查詢結構及中列明對應的關系:resultMap
● 控制動態sql拼接:if、foreach、choose
● 格式化輸出:where、set、trim
● 配置關聯關系:collection、association
● 定義常量及引用:sql、include

MyBatis提供了對SQL語句動態的組裝能力,大量的判斷都可以在 MyBatis的映射XML文件里面配置,以達到許多我們需要大量代碼才能實現的功能,大大減少了我們編寫代碼的工作量。

1)動態SQL的元素

元素 作用 備注
if 判斷語句 單條件分支判斷
choose、when、otherwise 相當於 Java 中的 switch case default 語句 多條件分支判斷
trim、where、set 輔助元素 用於處理一些 SQL 拼裝問題
foreach 循環語句 在in語句等列舉條件常用

二、定義sql標簽

1)select 標簽

 - id:唯一的標識符

 - parameterType:傳給此語句的參數的全路徑名或別名 例:com.sikiedu.beans.User 或 user

 - resultType:語句返回值類型或別名。注意,如果是集合,那么這里填寫的是集合的泛型,而不是集合本身(resultType 與 resultMap 不能並用)

<select id="selectUserById" parameterType="User" resultType="User">
    SELECT * FROM user WHERE id = #{id}
</select>

2)insert 標簽

 - id:唯一的標識符

 - parameterType:傳給此語句的參數的全路徑名或別名 例:com.sikiedu.beans.User

<insert id="insertUser" parameterType="com.sikiedu.beans.User">
    INSERT INTO user VALUES(null,#{username},#{userpassword},#{balance},#{grgisterdate})
</insert>

3)delete 標簽

- 屬性同 insert

<delete id="deleteUserById" parameterType="Integer">
    DELETE FROM user WHERE id = #{id}
</delete>

4)update 標簽

- 屬性同 insert

<update id="updateUser" parameterType="com.sikiedu.beans.User">
    UPDATE user SET username = #{username} WHERE id = #{id}
</update>

三、動態 sql 拼接

1)if 標簽

if 標簽通常用於 WHERE 語句、UPDATE 語句、INSERT 語句中。

通過判斷參數值來決定是否使用某個查詢條件、判斷是否更新某一個字段、判斷是否插入某個字段的值。

<select id="selectRoleListByRole" parameterType="Role" resultMap="roleResultMap">
    SELECT * FROM user
    <where>
        <if test="level!=null and level!=''">
            level = #{level}
        </if>
        <if test="roletype!=null and roletype!=''">
            AND roletype = #{roletype}
        </if>
        <if test="userid!=null">
            AND userid = #{userid}
        </if>
    </where>
</select>

2)foreach 標簽

主要用於構建 in 條件,可在 sql 中對集合進行迭代。也常用到批量刪除、添加等操作中。

 - collection:collection 屬性的值有三個分別是 list、array、map 三種,分別對應的參數類型為:List、數組、map 集合。

 - item:表示在迭代過程中每一個元素的別名

 - index:表示在迭代過程中每次迭代到的位置(下標)

 - open:前綴

 - close:后綴

 - separator:分隔符,表示迭代時每個元素之間以什么分隔

<select id="selectRoleListByids" resultMap="roleResultMap">
    SELECT * FROM user
    WHERE idrole IN
    <foreach collection="array" item="id" open="(" separator="," close=")">
        ${id}
    </foreach>
</select>

3)choose標簽 - 類似於 Java 的 switch 語句

有時候我們並不想應用所有的條件,而只是想從多個選項中選擇一個。MyBatis 提供了 choose 元素,按順序判斷 when 中的條件出否成立,如果有一個成立,則 choose 結束。

當 choose 中所有 when的條件都不滿則時,則執行 otherwise 中的 sql。類似於 Java 的 switch 語句,choose 為 switch,when 為 case,otherwise 則為 default

<select id="getRoleListChoose" parameterType="Role" resultMap="roleResultMap">
    SELECT * FROM role
    <where>
        <choose>
            <when test="name!=null and name!='' ">
                AND name LIKE "%"#{name}"%"
            </when>
            <when test="userid!= null">
                AND userid = #{userid}
            </when>
            <otherwise>
                AND roletype = "射手"
            </otherwise>
        </choose>
    </where>
</select>

四、格式化輸出

1)where標簽 - 解決if標簽拼接字符串AND符號問題

當 if 標簽較多時,這樣的組合可能會導致錯誤。 如下:

<select id="getRoleListWhere" parameterType="Role" resultMap="roleResultMap">
    SELECT * FROM role WHERE
    <if test="name!=null and name!=' ' ">
        name = #{name}
    </if>
    <if test="roletype!=null and roletype!=' ' ">
        AND roletype = #{roletype}
    </if>
    <if test="userid!=null">
        AND userid = #{userid}
    </if>
</select>

當 name 值為 null 時,查詢語句會出現 “WHERE AND” 的情況,解決該情況除了將"WHERE"改為“WHERE 1=1”之外,還可以利用 where標簽。

這個“where”標簽會知道如果它包含的標簽中有返回值的話,它就插入一個‘where’。此外,如果標簽返回的內容是以 AND 或 OR 開頭的,則它會剔除掉。

<select id="selectRoleListByRole" parameterType="Role" resultMap="roleResultMap">
    <include refid="myselect"></include>
    <where>
        <if test="name!=null and name!=''">
            name = #{name}
        </if>
        <if test="roletype!=null and roletype!=''">
            AND roletype = #{roletype}
        </if>
        <if test="userid!=null">
            AND userid = #{userid}
        </if>
    </where>
</select>

2)set標簽 - 解決更新數據表時字符串拼接逗號”,”問題;

沒有使用 if 標簽時,如果有一個參數為 null,都會導致錯誤。

當在 update 語句中使用 if 標簽時,如果最后的 if 沒有執行,則或導致逗號多余錯誤。

使用 set 標簽可以將動態的配置 set 關鍵字,和剔除追加到條件末尾的任何不相關的逗號。

<update id="updateSetRole" parameterType="Role">
    UPDATE role
    SET name = '${name}',
    level = ${level},
    roletype = '${roletype}',
    userid = ${userid}
    WHERE idrole = #{id}
</update>

<update id="updateSetRole" parameterType="Role">
    UPDATE role SET
    <if test="name != null and name != ''">
        name = '${name}',
    </if>
    <if test="level != null">
        level = ${level},
    </if>
    <if test="roletype != null and roletype != ''">
        roletype = '${roletype}',
    </if>
    <if test="userid != null">
        userid = ${userid}
    </if>
    WHERE idrole = #{id}
</update>

使用 set+if 標簽修改后,如果某項為 null 則不進行更新,而是保持數據庫原值。

<update id="updateSetRole" parameterType="Role">
    UPDATE role
    <set>
        <if test="name != null and name != ''">
            name = '${name}',
        </if>
        <if test="level != null">
            level = ${level},
        </if>
        <if test="roletype != null and roletype != ''">
            roletype = '${roletype}',
        </if>
        <if test="userid != null">
            userid = ${userid}
        </if>
    </set>
    WHERE idrole = #{id}
</update>

3)trim 標簽

trim 標記是一個格式化的標記,主要用於拼接 sql 的條件語句(前綴或后綴的添加或忽略),可以完成 set 或者是 where 標記的功能

 - prefix:在trim標簽內sql語句加上前綴

 - suffix:在trim標簽內sql語句加上后綴

 - prefixOverrides:指定去除多余的前綴內容,如:prefixOverrides=“AND | OR”,去除trim標簽內sql語句多余的前綴"and"或者"or"。

 - suffixOverrides:指定去除多余的后綴內容。

<select id="selectRoleListByTrim" parameterType="Role" resultMap="roleResultMap">
    SELECT * FROM role
    <trim prefix="WHERE" suffixOverrides="AND">
        <if test="name!=null and name!=''">
            name = #{name} AND
        </if>
        <if test="roletype!=null and roletype!=''">
            roletype = #{roletype} AND
        </if>
        <if test="userid!=null">
            userid = #{userid} AND
        </if>
    </trim>
</select>

如果name、roletype和userid的值都不為空的話,會執行如下語句

SELECT * FROM role WHERE name = #{name} AND roletype = #{roletype} AND userid = #{userid}

會為片段添加 “WHERE” 前綴,並忽略最后個 “and” 

五、定義常量及引用

1)sql標簽 - 可以提取重復sql語句片段

當多種類型的查詢語句的查詢字段或者查詢條件相同時,可以將其定義為常量,方便調用。為求 <select> 結構清晰也可將 sql 語句分解。

<sql id="myselect">
    SELECT * FROM role
</sql>

2)include - 用於引用定義的常量

<resultMap type="Role" id="roleRM">
    <id property="id" column="idrole" />
</resultMap>
<select id="selectAllRole" resultMap="roleRM">
    <include refid="myselect"></include>
</select>

<select id="selectRoleListByids" resultMap="roleRM">
    <include refid="myselect"></include>
    WHERE idrole IN
    <foreach collection="array" item="id" open="(" separator="," close=")">
        ${id}
    </foreach>
</select>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM