
在用户注册的时候,可能会有这样一个问题,如下:

注册分为两种字段:
这个时候就需要使用动态标签来判断了,比如添加的时候性别 gender 为非必填字段,具体实现如下:
接口定义:p
Integer insertUserByCondition(UserInfo userInfo);Mapper.xml 实现
<insert id="insertUserByCondition">
insert into userinfo (username, 'password', age, <if test="gender != null">gender,</if> phone)
value (#{username}, #{age}, <if test="gender != null">#{gender},</if>> #{phone})
</insert>此方法不推荐
把上面的 SQL(包括标签),使用 <script></script> 括起来就行
之前的插入用户功能,只是有一个 gender 字段可能是选填项,如果有多个字段,一般考虑使用标签结合标签,对多个字段都采取动态生成的方式。
标签中有如下属性:
prefix:表示整个语句块以 prefix 的值作为前提suffix:表示整个语句块以 suffix 的值作为后缀prefixOverrides:表示整个语句块要去除掉的前缀suffixOverrides:表示整个语句块要去除掉的后缀调整 Mapper.xml 的插入语句为:
<insert id="insertUserByTrim">
insert into userinfo
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">
username,
</if>>
<if test="password != null">
password,
</if>
<if test="age != null">
age,
</if>
<if test="gender != null">
gender,
</if>
<if test="phone != null">
phone,
</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">
#{username},
</if>>
<if test="password != null">
#{password},
</if>
<if test="age != null">
#{age},
</if>
<if test="gender != null">
#{gender},
</if>
<if test="phone != null">
#{phone},
</if>
</trim>
</insert>在以上 SQL 动态解析时,会将第一个部分做如下处理:
prefix 配置,开始部分加上 (suffix 配置,结束部分加上 ), 结尾,在最后拼接好的字符串还会以 , 结尾,会基于 suffixOverrides 配置去掉最后一个 ,<if test+"username != null"> 中的 username 是传入对象的属性看下面的场景,系统会根据我们筛选条件,动态组装 where 条件

这种如何实现呢?接下来我们看代码实现
需求:传入的用户对象,根据属性做 where 条件查询,用户对象中属性不为 null 的,都为查询条件
username 为 a,则查询条件为 where username=“a”原有 SQL:
select * from userinfo where age = 18 and gender = 1接口定义:
List<UserInfo> queryByWhere();<select id="selectUserByWhere" resultType="com.glg.mybatis.model.UserInfo">
select id, username, age, gender from userinfo
<where>
<if test="age != null">
and age = #{age}
</if>
<if test="gender != null">
and gender = #{gender}
</if>
</where>
</select><where> 只会在子元素有内容的情况下才插入 where 自居,而且会自动去除句子开头的 and 或 or<trim prefix="where" prefixOverrides="and"> 替换,但是此种情况下,当子元素都没有内容时,where 关键字也会保留需求:根据传入的用户对象属性来更新用户数据,可以使用标签来指定动态内容
接口定义:根据传入的用户 id 属性,修改其他不为 null 的属性
Integer updateUserBySet();Mapper.xml
<update id="updateUserBySet">
update userinfo
<set>
<if test="username != null">
username = #{username}
</if>
<if test="age != null">
age = #{age}
</if>
</set>
where id = #{id}
</update><set>:动态的在 SQL 语句中插入 set 关键字,并会删除掉额外的逗号(用于 update 语句中),以上标签也可以使用 <trim prefix="set" suffixOverrides=","> 替换对集合进行遍历时可以用该标签,标签有如下属性
collection:绑定方法参数中的集合,如 List,Set,Map 或数组对象item:遍历时的每一个对象open:语句块开头的字符串close:语句块结束的字符串separator:每次遍历之间间隔的字符串需求:根据多个 userid,删除用户数据
接口方法:
void deleteBySet(List<Integer> ids);ArticleMapper.xml 中新增删除 SQL:
<delete id="deleteUserBySet">
delete from userinfo where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>问题分析:
xml 映射文件中配置的 SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码
我们可以对重复的代码片段进行抽取,将其通过 <sql> 标签封装到一个 SQL 片段,然后再通过 <include> 标签进行引用
<sql>:定义可重复用的 SQL 片段<include>:通过属性 refid,指定包含的 SQL 片段