首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Java EE进阶 --- SpringBoot】Mybatis操作数据库(进阶)

【Java EE进阶 --- SpringBoot】Mybatis操作数据库(进阶)

作者头像
optimistic_chen
发布2026-01-14 20:32:10
发布2026-01-14 20:32:10
60
举报

动态SQL

动态 SQL 是 MyBatis 的强大特性之一。如果使用JDBC等框架,拼接SQL语句是一件很痛苦的事。现在使用MyBatis能够完成不同条件下不同的SQL拼接。

< if >标签

当我们在注册登录时,面临填写必要信息的情况,密码等字段是必填字段,生日等类似的字段是非必填字段。那在注册(添加)用户时,我们不确定用户填写的字段传入(可能会填也可能不会填),程序要如何编写呢?

这个时候需要动态标签来判断了 定义Mapper接口:

代码语言:javascript
复制
@Mapper
public interface UserInfoMapperXML {
    Integer insertUser3(UserInfo userInfo);
}

数据库中可以设置字段的默认值,如果未传入参数,那就会使用数据库中默认值 xml实现:

代码语言:javascript
复制
<insert id="insertUser3">
        insert into user_info (
        username,
        `password`,
        age,
        <if test="gender !=null>//如果gender参数不为null,此处使用属性名称
             gender,//拼接SQL字段,使用字段名
        </if>
        phone)
        values(
        #{username},
        #{age},
        <if test="gender !=null>//如果gender参数不为null,赋值
             #{gender},//进行赋值
        </if>
        #{phone})
    </insert>

< trim >标签

前面只是一个gender字段是选填项,如果有多个字段是选填(提前设置好数据库字段的结构),我们要使用 标签结合标签,对多个字段采用动态生成的方法。 首先,介绍一下< trim>标签的属性(后面会用到): prefix: 为SQL语句添加前缀。 suffix: 为SQL语句添加后缀。 prefixOverrides: 去除SQL语句前面的关键字或字符。 suffixOverrides: 去除SQL语句后面的关键字或字符

现在有两个选填,我们运行测试一下:

代码语言:javascript
复制
<insert id="insertUser3">
        insert into user_info (username,`password`,age,
            <if test="gender!=null">
                gender,
            </if>
            <if test="phone!=null">
                phone
            </if>
        )
        VALUES (#{username},#{password},#{age},
            <if test="gender!=null">
                #{gender},
            </if>
            <if test="phone!=null">
                #{phone}
            </if>
        )
    </insert>
在这里插入图片描述
在这里插入图片描述

当选填的两个选项都为空时,会发现报错,仔细观察。 报错原因是:逗号;三个选项填完后,age后面有一个逗号,但是按照上面的情况会发现age后面木有选项了,这个逗号应该怎么办呢?

或许有聪明的大佬会说:把逗号放在属性的前面,就可以正常运行了

在这里插入图片描述
在这里插入图片描述

但是如果不止两个选填,字段全是选填 该如何放置呢? 按照大佬的思路,继续放到字段前面:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

显然,这个办法在多个选填面前失效了。此时就需要拿出前面给出的标签属性了。

代码语言:javascript
复制
    <insert id="insertUser3">
        insert into user_info (
        <trim prefixOverrides=",">
            <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 prefixOverrides=",">
            <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>
在这里插入图片描述
在这里插入图片描述

< where>标签

我们在数据库中查询时,肯定要有查询条件,多个条件之间要用and连接。

定义Mapper接口:

代码语言:javascript
复制
    List<UserInfo> selectByCondition(UserInfo userInfo);

xml实现:从user表中查以phone和deleteFlag为条件的数据

代码语言:javascript
复制
<select id="selectByCondition" resultType="com.zc.mybatis.model.UserInfo">
        select *from user_info
        where phone=#{phone} and delete_flag=#{deleteFlag}
</select>     

但是在各大购物平台,都有商品筛选功能,他的实现就是动态组装where条件

在这里插入图片描述
在这里插入图片描述

仿照前面标签的做法,选择多个选项时,使用prefixOverrides去除前缀(否则会出现SQL语句错误的情况哦)

代码语言:javascript
复制
<select id="selectByCondition" resultType="com.zc.mybatis.model.UserInfo">
        select *from user_info
        <trim prefixOverrides="and">
            <if test="phone!=null">
                and phone=#{phone}
            </if>
            <if test="deleteFlag!=null">
                and delete_flag=#{deleteFlag}
            </if>
        </trim>
</select>

当然,你也可以使用where标签: 当where语句为空时,会去除where关键字 当where语句块有查询条件时,会添加where关键字,也会去除前缀and关键字,使用更加便利。

代码语言:javascript
复制
<select id="selectByCondition" resultType="com.zc.mybatis.model.UserInfo">
        select *from user_info
        <where>
            <if test="phone!=null">
                and phone=#{phone}
            </if>
            <if test="deleteFlag!=null">
                and delete_flag=#{deleteFlag}
            </if>
        </where>
</select>
在这里插入图片描述
在这里插入图片描述

< set>标签

根据传入用户对象属性来更新用户数据,可以使用标签指定动态内容 xml实现:

代码语言:javascript
复制
<update id="updateByCondition">
        update user_info
        <set>
            <if test="password!=null">
                password=#{password},
            </if>
            <if test="age!=null">
                age=#{age},
            </if>
            <if test="gender!=null">
                gender=#{gender}
            </if>
        </set>
        where id=#{id}//更新条件
    </update>
在这里插入图片描述
在这里插入图片描述

注意:set标签:动态的在SQL语句中插⼊set关键字,并会删掉额外的逗号.当然,你也可以根据< trim>标签替换

< foreach>标签

对集合进行遍历使用该标签,属性如下: collection:绑定⽅法参数中的集合,如List,Set,Map或数组对象 item:遍历的每一个对象 open:语句开头的字符串 close:语句结束的字符串 separator:每次遍历之间间隔的字符串

mapper接口:

代码语言:javascript
复制
Integer batchDelete(List<Integer> ids);

xml实现:根据多个id,删除用户数据

代码语言:javascript
复制
<delete id="batchDelete">
        delete from user_info where id in
        //collection="ids":元素集合
       //item="id":元素变量名
       //separator=",":元素分隔符
        <foreach collection="ids" open="(" close=")" separator="," item="id">
            #{id}
        </foreach>
    </delete>
在这里插入图片描述
在这里插入图片描述

< include>标签

在xml映射⽂件中配置的SQL,有时可能会存在很多重复的⽚段,此时就会存在很多冗余的代码

我们通过对这些代码进行抽取,将其封装到一个SQL片段,然后再通过< include> 标签引用

代码语言:javascript
复制
//<sql>定义可重用的sql片段 
 <sql id="allColumn">
       id, username, age, gender, phone, delete_flag, create_time, update_time
 </sql>

通过< include>标签在原来抽取的地方进行引用即可

代码语言:javascript
复制
 <select id="queryById" resultType="com.example.demo.model.UserInfo">
        select
        <include refid="allColumn"></include>
        from userinfo where id= #{id}
 </select>

完结撒花!🎉

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 动态SQL
    • < if >标签
    • < trim >标签
    • < where>标签
    • < set>标签
    • < foreach>标签
    • < include>标签
  • 完结撒花!🎉
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档