在用户注册的时候,可能会有这样一个问题,如下:
注册分为两种字段:
这个时候就需要使用动态标签来判断了,比如添加的时候性别 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
片段