MyBatis 的动态 SQL 是一种强大的特性,它可以让你在 XML 映射文件内,根据不同的条件编写不同的 SQL 语句。MyBatis 动态 SQL 主要元素有:
<if>
: 根据提供的条件来动态拼接 SQL。
接口定义
Integer insertUserByCondition(UserInfo userInfo);
Mapper.xml实现
<insert id="insertUserByCondition">INSERT INTO userinfo (username,`password`,age,<if test="gender != null">gender,</if>phone)VALUES (#{username},#{age},<if test="gender != null">#{gender},</if>#{phone})
</insert>
<trim>标签
标签中有如下属性:
• prefix:表⽰整个语句块,以prefix的值作为前缀
• suffix:表⽰整个语句块,以suffix的值作为后缀
• prefixOverrides:表⽰整个语句块要去除掉的前缀
• suffixOverrides:表⽰整个语句块要去除掉的后缀
<insert id="insertUserByCondition">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>
: 自动处理前导的 AND
或 OR
语句。
接口定义
List<UserInfo> queryByCondition();
Mapper.xml实现
<select id="queryByCondition" resultType="com.example.demo.model.UserInfo">select id, username, age, gender, phone, delete_flag, create_time,
update_timefrom userinfo<where><if test="age != null">and age = #{age}</if><if test="gender != null">and gender = #{gender}</if><if test="deleteFlag != null">and delete_flag = #{deleteFlag}</if></where>
</select>
<where> 只会在⼦元素有内容的情况下才插⼊where⼦句,⽽且会⾃动去除⼦句的开头的AND或
OR
以上标签也可以使⽤ <trim prefix="where" prefixOverrides="and"> 替换,但是此种情况下,当⼦元素都没有内容时,where关键字也会保留
<set>
: 自动处理后面的逗号问题。
接⼝定义:根据传⼊的⽤⼾id属性,修改其他不为null的属性
Integer updateUserByCondition(UserInfo userInfo);
Mapper.xml
<update id="updateUserByCondition">update userinfo<set><if test="username != null">username = #{username},</if><if test="age != null">age = #{age},</if><if test="deleteFlag != null">delete_flag = #{deleteFlag},</if></set>where id = #{id}
</update>
<set> :动态的在SQL语句中插⼊set关键字,并会删掉额外的逗号.(⽤于update语句中)
<foreach>
: 主要用于处理数组、集合的元素。
对集合进⾏遍历时可以使⽤该标签。标签有如下属性:
• collection:绑定⽅法参数中的集合,如List,Set,Map或数组对象
• item:遍历时的每⼀个对象
• open:语句块开头的字符串
• close:语句块结束的字符串
• separator:每次遍历之间间隔的字符串
需求:根据多个userid,删除⽤⼾数据
接⼝⽅法:
void deleteByIds(List<Integer> ids);
ArticleMapper.xml中新增删除sql:
<delete id="deleteByIds">delete from userinfowhere id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
</delete>
<include> :通过属性refid,指定包含的SQL⽚段
我们可以对重复的代码⽚段进⾏抽取,将其通过 <sql> 标签封装到⼀个SQL⽚段,然后再通过
<include> 标签进⾏引⽤。
• <sql> :定义可重⽤的SQL⽚段
• <include> :通过属性refid,指定包含的SQL⽚段
<sql id="allColumn">id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>
通过 <include> 标签在原来抽取的地⽅进⾏引⽤。操作如下:
<select id="queryAllUser" resultMap="BaseMap">select<include refid="allColumn"></include>from userinfo
</select>
<select id="queryById" resultType="com.example.demo.model.UserInfo">select<include refid="allColumn"></include>from userinfo where id= #{id}
</select>