MyBatis 的動態 SQL 包括以下幾種元素:
詳細的使用參考官網文檔:http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html
本章內容簡單描述這些動態 SQL 在使用的過程中需要注意的地方。
choose, when, otherwise
比如我們要實現如下功能:
- 當學生姓名不爲空,則只用學生姓名作爲條件查詢
- 當學生性別不爲空,則只用學生性別作爲條件查詢
- 當學生姓名和學生性別都爲空,則要求學生學生證件號不爲空
針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。
<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_student
<where>
<choose>
<when test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</when>
<when test="sex != null">
AND sex = #{sex}
</when>
<otherwise>
AND selfcard_no is not null
</otherwise>
</choose>
</where>
</select>
trim, where, set
比如下面的動態 SQL 有什麼問題?
<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
SELECT id, name, sex, selfcard_no, note
FROM t_student
WHERE
<if test="ids != null and ids.size() > 0">
id IN
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="selfcardNo != null">
AND selfcard_no = #{selfcardNo}
</if>
</select>
如果這些條件沒有一個能匹配上會發生什麼?最終這條 SQL 會變成這樣:
SELECT id, name, sex, selfcard_no, note
FROM t_student
WHERE
這樣會導致 SQL 語句執行失敗。如果僅僅第二個條件匹配又會怎樣?這條 SQL 最終會是這樣:
SELECT id, name, sex, selfcard_no, note
FROM t_student
WHERE
AND name LIKE CONCAT('%', 'a', '%')
這個查詢也會失敗。
MyBatis 提供了 <where> 元素可以解決上面的問題,將上面的動態 SQL 改成如下形式。
<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
SELECT id, name, sex, selfcard_no, note
FROM t_student
<where>
<if test="ids != null and ids.size() > 0">
AND id IN
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="selfcardNo != null">
AND selfcard_no = #{selfcardNo}
</if>
</where>
</select>
foreach
實現批量新增功能,動態 SQL 如下:
<insert id="batchInsertByNoAutoInc" parameterType="list">
<selectKey keyProperty="id" resultType="long" order="BEFORE">
select if(max(id) is null, 1, max(id) + 2) as newId from t_student
</selectKey>
insert into t_student (name, sex, selfcard_no, note)
values
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.name,jdbcType=VARCHAR},
#{item.sex,jdbcType=TINYINT},
#{item.selfcardNo,jdbcType=BIGINT},
#{item.note,jdbcType=VARCHAR}
)
</foreach>
</insert>
批量新增的操作需要確保 list 中必須有值。
MyBatis 實用篇