Mybatis引出的一系列问题-动态 SQL

这篇具有很好参考价值的文章主要介绍了Mybatis引出的一系列问题-动态 SQL。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

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

1 if

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:

<select id="findActiveBlogWithTitleLike" resultType="Blog">
  SELECT * FROM BLOG
  WHERE state =ACTIVE<if test="title != null">
    AND title like #{title}
  </if>
</select>

这条语句提供了可选的查找文本功能。如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 BLOG 都会返回;如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果(细心的读者可能会发现,“title” 的参数值需要包含查找掩码或通配符字符)。

如果希望通过 “title” 和 “author” 两个参数进行可选搜索该怎么办呢?首先,我想先将语句名称修改成更名副其实的名称;接下来,只需要加入另一个条件即可。

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state =ACTIVE<if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

2 choose、when、otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句

还是上面的例子,但是策略变为:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG(这可能是管理员认为,与其返回大量的无意义随机 Blog,还不如返回一些由管理员精选的 Blog)。

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state =ACTIVE<choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

3 trim、where、set

前面几个例子已经方便地解决了一个臭名昭著的动态 SQL 问题。现在回到之前的 “if” 示例,这次我们将 “state = ‘ACTIVE’” 设置成动态条件,看看会发生什么。

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  WHERE
  <if test="state != null">
    state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

如果没有匹配的条件会怎么样?最终这条 SQL 会变成这样:

SELECT * FROM BLOG
WHERE

这会导致查询失败。如果匹配的只是第二个条件又会怎样?这条 SQL 会是这样:

SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’

这个查询也会失败。这个问题不能简单地用条件元素来解决。这个问题是如此的难以解决,以至于解决过的人不会再想碰到这种问题。

MyBatis 有一个简单且适合大多数场景的解决办法。而在其他场景中,可以对其进行自定义以符合需求。而这,只需要一处简单的改动:

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

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

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:文章来源地址https://www.toymoban.com/news/detail-624836.html

  <update id="updateBatch" parameterType="java.util.List">
    <!--@mbg.generated-->
    update bs_factory_calendar
    <trim prefix="set" suffixOverrides=",">
      <trim prefix="SET_TIME = case" suffix="end,">
        <foreach collection="list" index="index" item="item">
          when FACTORY_CALENDAR_ID = #{item.factoryCalendarId,jdbcType=VARCHAR} then #{item.setTime,jdbcType=VARCHAR}
        </foreach>
      </trim>
      <trim prefix="WEEK = case" suffix="end,">
        <foreach collection="list" index="index" item="item">
          when FACTORY_CALENDAR_ID = #{item.factoryCalendarId,jdbcType=VARCHAR} then #{item.week,jdbcType=VARCHAR}
        </foreach>
      </trim>
    </trim>
    where FACTORY_CALENDAR_ID in
    <foreach close=")" collection="list" item="item" open="(" separator=", ">
      #{item.factoryCalendarId,jdbcType=VARCHAR}
    </foreach>
  </update>

  <insert id="insertOrUpdateSelective" parameterType="com.inspur.spring.pojo.BsFactoryCalendar">
    <!--@mbg.generated-->
    insert into bs_factory_calendar
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="factoryCalendarId != null">
        FACTORY_CALENDAR_ID,
      </if>
      <if test="setTime != null">
        SET_TIME,
      </if>
    </trim>
    values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="factoryCalendarId != null">
        #{factoryCalendarId,jdbcType=VARCHAR},
      </if>
      <if test="setTime != null">
        #{setTime,jdbcType=VARCHAR},
      </if>
    </trim>
    on duplicate key update
    <trim suffixOverrides=",">
      <if test="factoryCalendarId != null">
        FACTORY_CALENDAR_ID = #{factoryCalendarId,jdbcType=VARCHAR},
      </if>
      <if test="setTime != null">
        SET_TIME = #{setTime,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>

  <update id="updateByPrimaryKeySelective" parameterType="com.inspur.spring.pojo.BsFactoryCalendar">
    <!--@mbg.generated-->
    update bs_factory_calendar
    <set>
      <if test="updateTime != null">
        UPDATE_TIME = #{updateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="comId != null">
        COM_ID = #{comId,jdbcType=VARCHAR},
      </if>
    </set>
    where FACTORY_CALENDAR_ID = #{factoryCalendarId,jdbcType=VARCHAR}
  </update>

4 foreach

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  <where>
    <foreach item="item" index="index" collection="list"
        open="ID in (" separator="," close=")" nullable="true">
          #{item}
    </foreach>
  </where>
</select>

到了这里,关于Mybatis引出的一系列问题-动态 SQL的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MSVS C# Matlab的混合编程系列1 - 看似简单的问题引出

    问题提出,如何把Matlab(本文简称MT)的算法集成到Visual Studio(本文简称VS)里面运行? 本文,通过编制一个MT中最简单的加法函数,我们把他做成 MSVS C#能够使用的动态库,说明了MSVS C# 和 MT集成的最小,然而,最简洁清晰的处理方法和过程。  1 VS2019 2 C# .Net 应用环境 3 MT2019 指的

    2024年01月21日
    浏览(36)
  • 【MyBaits】4、延迟加载、MyBatis 的缓存

    🍃 关联对象( association 、 collection )可以实现延迟加载 🍃 实现延迟加载需设置如下属性 fetchType :设置为 lazy select :指定一个 select 标签的 id(用于查询需要延迟加载的记录) column :指定一个列的值(作为 select 查询时传入的参数值) 🍃 一般会给 collection 设置延迟加载

    2024年02月09日
    浏览(40)
  • 关于括号的一系列问题

    对于只出现一种括号的字符串,看这个字符串中的括号是否匹配 以及 匹配的个数: 一般来说有两种匹配方式: 例如: (()()()) 第一种匹配是此字符串有4组括号对匹配完成 第二种匹配是此字符串有3组括号对匹配完成 对于第一种匹配方式:有两种选择:栈或者直接

    2024年02月11日
    浏览(28)
  • MyBatis 中的动态 SQL 是什么? 如何使用动态 SQL?

    在 MyBatis 中,动态 SQL 是指能够根据条件动态生成 SQL 语句的功能。通过使用动态 SQL,可以根据不同的条件生成不同的 SQL 语句,从而实现灵活的查询和操作。 条件判断:通过 , , , 标签实现 SQL 语句中的条件逻辑,根据传入参数的值来决定是否包含某一部分 SQL 语句。 循环遍

    2024年04月15日
    浏览(31)
  • 认识MyBatis 之 MyBatis的动态SQL

    本篇介绍MyBatis里如何使用动态SQL,了解如何去简单使用动态标签;如有错误,请在评论区指正,让我们一起交流,共同进步! 本文开始 使用动态SQL的好处:根据不同的条件拼接 SQL 语句,提高了SQL的灵活性; if标签:判断时使用,满足test中的判断,执行if条件 格式: if te

    2024年02月14日
    浏览(41)
  • 安装fasttext的一系列问题(全)

    环境配置:windows10+python3.10 前言:Gensim中的fasttext不能做文本分类,对于想学习fasttext进行文本分类、情感分析的同学还是必须下载Facebook的fasttext 在该python libs (或者粘贴该链接https://www.lfd.uci.edu/~gohlke/pythonlibs/#fasttext)搜索fasttext 下载whl文件,文件名: fasttext-0.9.2-cp310-cp31

    2024年02月06日
    浏览(60)
  • MyBatis之动态sql

    目录 一、MyBatis动态sql 1.1 是什么 1.2 作用 1.3 优点 1.4 特殊标签 1.5 代码演示 二、#和$的区别 2.1 #使用 2.2 $使用 2.3 综合 2.4 代码演示 三、resultType与resultMap的区别 3.1 关于resultType 3.2 关于resultMap   3.3 两者区别 3.4 代码演示 是一种在SQL语句中根据不同条件动态拼接SQL的方式。通

    2024年02月11日
    浏览(38)
  • MyBatis - 动态 SQL

    动态 SQL 是 MyBatis 提供的一个非常强大的功能,它可以让我们在运行时构建 SQL 语句。这意味着我们可以根据应用程序的需求来构建符合要求的 SQL。通常情况下,这是非常有用的,因为有时我们不知道要查询哪些表,或者要查询哪些列。此外,动态 SQL 还可以用来构建动态修改

    2024年02月07日
    浏览(52)
  • 【MyBatis】动态SQL

    动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。具体的定义大家可以参

    2024年01月17日
    浏览(45)
  • MyBatis:动态 SQL 标签

    MyBatis 动态 SQL 标签 ,是一组预定义的标签,用于构建动态的 SQL 语句,允许在 SQL 语句中使用条件、循环和迭代等逻辑。通过使用动态 SQL 标签,开发者可以根据不同的条件和参数生成不同的 SQL 语句,实现更加灵活的数据访问操作。但是,需要谨慎处理 SQL 注入问题,确保所

    2024年02月04日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包