Mybatis 那些 Xml 模板标签

发布于 2024-10-04 19:44:25 字数 6344 浏览 2 评论 0

SQL 标签

这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。

这里很明显就能看出来 SQL 标签一般是用于复用一组确定的列名 or

<sql id="userColumns">${tablename}.id,${tablename}.username,${tablename}.password</sql>
<select id="getUser" resultType="com.example.springmvclearn.entity.User">
    select
        <include refid="userColumns"><property name="tablename" value="user"/></include> 
        from user where id=1;
</select>
<!--    这里等效于   
    select user.id,user.username,user.password from user where id=1;
-->

tablename 对应下面 include 的 name 属性,用于确定要替换的位置

include 中的 value 用于确定 tablename 要替换成啥,这里就是替换成 user

#{} 和 ${}

#{}: 占位符,传入的内容会作为字符串 加上引号 ,以 预编译 的方式传入,将 sql 中的 #{} 替换为 ? 号,调用 PreparedStatement 的 set 方法来赋值,有效的防止 SQL 注入,提高系统安全性

${}: 拼接符,传入的内容会 直接替换 拼接,不会加上引号,可能存在 sql 注入的安全隐患

  • 能用 #{} 的地方就用 #{},不用或少用 ${}
  • 必须使用 ${} 的情况:
    • 表名作参数时,如: SELECT * FROM ${tableName}
    • order by 时,如: SELECT * FROM t_user ORDER BY ${columnName}
  • sql 语句使用 #{},properties 文件内容获取使用 ${}

动态 sql

动态 SQL 是 MyBatis 强大特性之一,逻辑复杂时,MyBatis 映射配置文件中,SQL 是动态变化的,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

动态 SQL 包含的标签:

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

if

if 标签使用是最常见的,和我们正常 java 语法的 if 差不多,看个例子就知道了

<select id="getUser" resultType="User">
    select * from user where 1=1
    <if test="id!=null">
        and id=#{id}
    </if>
</select>
<!--这里其实就是拼 sql,必须要有个 1=1 来让 id!=null 也能成功
    id==null 时:select * from user where 1=1
    id!=null 时:select * from user where 1=1 and id=#{id}
-->

choose、when、otherwise

这个类似与 java 语法中的 switch 与 case 和 default,

  • choose -> switch
  • when -> case
  • otherwise -> default

但是这里相比于 switch,他里面的 when 和 otherwize 只会触发一次,类似于 if else if else ,即代码块只会拼凑一个

接着看个栗子吧

<select id="getUser" resultType="User">
    select * from user where 1=1
    <choose>
        <when test="id!=null">
            and id=#{id}
        </when>
        <when test="username!=null and username!=''">
            and username=#{username}
        </when>
        <when test="password!=null and password!=''">
            and password=#{password}
        </when>
        <otherwise>
            and ~~~~自己定义吧
        </otherwise>
    </choose>
</select>

trim、where、set

where

先来看 where 吧,还记得上面我们写的 where 1=1 以及if 标签里面的 and 吗?,再来回顾一下上面可能出现的问题

-- 如果没有 1=1 的话且 if 标签判断的是 false
select * from user where --戛然而止了
-- 如果没有 1=1 的话且 if 标签里面判断成功,但是没有 and
select * from user where 1=1   ???   id=#{id} --缺少 and

为了是不是觉得为了解决 sql 拼凑的错误,要写这个 1=1 或者 and 很丑陋,在这里where 标签就解决了这个问题,以上面的 if 的例子来说明吧

<select id="getUser" resultType="User">
    select * from user
    <where>
        <if test="id!=null">
        and id=#{id}
        </if>
    </where>
</select>

是不是看着舒服多了。看看 where 标签做了啥呢?

where 标签只会在子元素返回任何内容的情况下才插入 WHERE 子句。而且,若子句的开头为 ANDOR ,where 元素也会将它们去除。

trim

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 标签。

trim 有如下参数可以选择

  • prefix:给拼串后的整个字符串加一个前缀,trim 标签体中是整个字符串拼串后的结果
  • prefixOverrides:去掉整个字符串前面多余的字符
  • suffix:给拼串后的整个字符串加一个后缀
  • suffixOverrides:去掉整个字符串后面多余的字符

我们类似可以这样实现where 标签类似的功能

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

来看个具体点的栗子

<select id="selectUserByUsernameAndPassword" resultType="User">
    SELECT * FROM user
    <trim prefix="where" prefixOverrides="and | or">
        <if test="username != null">
            AND username=#{username}
        </if>
        <if test="password != null">
            AND password=#{password}
        </if>
    </trim>
</select>

set

set :进行更新操作的时候,含有 set 关键词,使用该标签

<!-- 根据 id 更新 user 表的数据 -->
<update id="updateUserById">
    UPDATE user
        <set>
            <if test="username != null and username != ''">
                username = #{username},
            </if>
            <if test="password != null and password != ''">
                password = #{password}
            </if>
        </set>
     WHERE id=#{id}
</update>
  • 如果第一个条件 username 为空,那么 sql 语句为:update user u set password=? where id=?
  • 如果第一个条件不为空,那么 sql 语句为:update user u set u.username = ? ,u.password = ? where id=?

同时set 其实也能用trim 实现,这里其实主要就是删除掉最后的逗号

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

foreach

这个其实也与 java 语法中的 for 循环差不多

foreach 提供了如下参数选择:

  • collection 集合参数的名称,看个方法签名, List<User> selectByIds(@Param("ids") List<Integer> ids); 这里只要填 ids 即可
  • close 结束的 SQL 语句
  • index 此时遍历到参数的下标(从 0 开始)
  • item 参数变量名
  • open 开始的 SQL 语句
  • separator 分隔符

定义那么多,看个栗子吧

<select id="selectByIds" resultType="user" >
    SELECT * FROM user where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
<!--这里 foreach 生成的就是(id1,id2,id3,~~~) 这种啦-->
<!--注意 collection="list" 这里意味着 mapper 的中接口的方法签名得是这样的 List<User> selectByIds(List<Integer> ids)
也就是说容器类型得是 list
-->
</select>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

上一篇:

下一篇:

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

平生欢

暂无简介

0 文章
0 评论
591 人气
更多

推荐作者

謌踐踏愛綪

文章 0 评论 0

开始看清了

文章 0 评论 0

高速公鹿

文章 0 评论 0

alipaysp_PLnULTzf66

文章 0 评论 0

热情消退

文章 0 评论 0

白色月光

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文