傳統 JDBC 拼接 SQL:字串連接易漏空格、SQL 注入風險、難維護。MyBatis 提供 6 大標籤,基於 OGNL 表達式構建動態 SQL,安全優雅。
| 標籤 | 用途 | 關鍵屬性 |
|---|---|---|
<if> | 單條件判斷 | test |
<where> | 智能 WHERE 子句 | 自動去首部 AND/OR |
<set> | 智能 UPDATE 子句 | 自動去尾部逗號 |
<trim> | 通用前後綴處理 | prefix/suffix/prefixOverrides/suffixOverrides |
<choose/when/otherwise> | 互斥分支 | test |
<foreach> | 集合迭代 | collection/item/index/open/separator/close |
<select id="findUser" resultType="User">
SELECT * FROM user
<where>
<if test="username != null and username != ''">
username = #{username}
</if>
<if test="status != null">
AND status = #{status}
</if>
<if test="age != null">
AND age >= #{age}
</if>
</where>
</select>
若所有條件皆假,生成 SELECT * FROM user(無 WHERE)。
<update id="updateUser" parameterType="User">
UPDATE user
<set>
<if test="username != null">username = #{username},</if>
<if test="email != null">email = #{email},</if>
<if test="age != null">age = #{age}</if>
</set>
WHERE id = #{id}
</update>
若僅更新 username,生成 UPDATE user SET username = ? WHERE id = ?(無尾逗號)。
<select id="findByIds" resultType="User">
SELECT * FROM user
<where>
id IN
<trim prefix="(" suffix=")" suffixOverrides=",">
<foreach collection="list" item="id" separator=",">#{id}</foreach>
</trim>
</where>
</select>
<select id="findActiveBlog" resultType="Blog">
SELECT * FROM blog WHERE state = 'ACTIVE'
<choose>
<when test="title != null">AND title LIKE #{title}</when>
<when test="author != null">AND author_name LIKE #{author.name}</when>
<otherwise>AND featured = 1</otherwise>
</choose>
</select>
<!-- 批量查詢 -->
<select id="batchSelect" resultType="User">
SELECT * FROM user WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach>
</select>
<!-- 批量插入 -->
<insert id="batchInsert">
INSERT INTO user (username, email) VALUES
<foreach collection="list" item="user" separator=",">
(#{user.username}, #{user.email})
</foreach>
</insert>
test="name != null"@Param("paramName"),XML 中用 #{paramName.property}test="map.key != null"map["list"]/map["array"]
property != null
property != null and property != ''
collection != null and collection.size() > 0
@org.apache.commons.lang3.StringUtils@isNotBlank(property)
property == 'VALUE'
property in {'A','B','C'}
MyBatis 動態 SQL 核心是「標籤語義化 + OGNL 表達式 + 參數規範」。掌握 6 大標籤組合、@Param 多參數處理、trim 通用前後綴原理,即可應對所有動態構建場景。生產建議:複雜 SQL 拆分為多個 select 片段,用 <include> 復用。