动态SQL:允许根据参数不同,来生成不同的SQL语句。
【需求】根据若干个id删除数据表数据
需要执行的SQL语句大致是:
DELETE FROM pms_brand WHERE id=? OR id=? …… OR id=?;
或者是:
DELETE FROM pms_brand WHERE id IN (?, ?, .... ?);
在以上SQL中,需要被删除的数据的id的数量是不确定的!
在实现此需求时,抽象方法可以设计为:
int deleteByIds(List<Long> ids);
int deleteByIds(Long[] ids);
int deleteByIds(Long... ids); // deleteByIds(1,2,3,4,5)
在配置SQL时,需要使用到<foreach>
标签对参数进行遍历:
<!-- int deleteByIds(List<Long> ids); -->
<delete id="deleteByIds">
DELETE FROM pms_brand WHERE id IN (
<foreach collection="list" item="id" separator=",">
#{id}
</foreach>
)
</delete>
关于<foreach>
标签的属性:
-
collection
:表示被遍历的参数对象,当抽象方法的参数只有1个时,如果参数类型是List
,则此属性值为list
,如果参数类型是数组(或可变参数),则此属性值为array
-
item
:遍历过程中的每个元素的名称,是自定义的名称,并且,在<foreach>
标签内部,使用#{}
时的名称也就是此属性的值(此处自定义的名称) -
separator
:遍历过程中在值之前添加的分隔符号
【需求】根据id修改数据表的数据,参数中传入了哪些属性,就修改对应的那些字段的值
需要执行的SQL语句大致是:
update pms_brand set name=?, pinyin=?, logo=? ....(修改其它字段的值) where id=?
则抽象方法可以设计为:
int updateById(Brand brand);
然后,配置SQL语句:
<update id="updateById">
UPDATE
pms_brand
<set>
<if test="name != null">
name=#{name},
</if>
<if test="pinyin != null">
pinyin=#{pinyin},
</if>
...
...
</set>
WHERE
id=#{id}
</update>
以上代码中,使用到了2个标签:
-
<if>
:用于对参数的值进行判断,从而决定SQL语句中是否包含<if>
子级的SQL片段 -
<set>
:用于取代SET
关键字,通常结合若干个<if>
一起使用,可以去除更新的SQL语句中的字段列表与值最后多余的逗号
注意:<if>
标签并没有匹配的类似else
的标签,如果需要实现类似Java代码中的if...else...
的效果,可以:
<if test="某条件">
满足条件时的SQL片段
</if>
<if test="与以上完全相反的条件">
满足本if时的SQL片段
</if>
以上示例可以实现类似if...else...
的效果,但是,更像是if...
与另一个if...
,本质上是执行了2次判断的!
另外,还可以使用<choose>
系列标签,真正的实现类似if...else...
的效果:
<choose>
<when test="判断条件">
满足条件时的SQL片段
</when>
<otherwise>
不满足条件时的SQL片段
</otherwise>
</choose>