首页 > 数据库 >MyBatis动态SQL

MyBatis动态SQL

时间:2024-04-12 15:13:43浏览次数:25  
标签:语句 判断 jdbcType SQL MyBatis 动态 id

MyBatis动态SQL

动态SQL简介

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

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

常用的动态SQL标签

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

为什么要用动态SQL

动态SQL可以根据传入的查询条件,灵活的拼接SQL语句

动态SQL用法

if标签

if标签语法

<select...>
  SQL语句1
  <if test="条件表达式">
     SQL语句2
  </if>
</select>

条件表达式大于、小于、大于等于、小于等于判断
image

if条件判断各种使用方式

  1. 如果参数为数字类型的时候没有特俗需求的情况只需要判断是否为null即可

例如:

<if test="id != null"> </if>

如果有特俗需求,例如判断是否大于某个数的时候才行。只需要加上对应的条件判断即可

例如:

<if test='id != null and id > 28'></if>

mybatis对于这种大于小于等等还有另一种形式

例如:

<if test='id != null and id gt 28'></if>

对应关系:

image

  1. 如果参数字符串类型
  • 如果不需要过滤空串的情况 仅仅判断null即可
<if test="username != null"></if>
  • 如果需要过滤空串,添加空串判断即可 不支持 && 所以这里用 and or || 来做逻辑与或的判断
<if test="username != null and '' != username"></if> 
或者 
<if test="username != null and ''  neq username"></if>
  • 如果判断字符串是否已某个特俗字符开头,结尾等。直接调用String的对应方法即可
<!-- 是否以什么开头 -->
<if test="username != null and username.indexOf('ji') == 0"> </if>
<!-- 是否包含某字符 -->
<if test="username != null and username.indexOf('ji') >= 0"> </if>
<!-- 是否以什么结尾 -->
<if test="username != null and username.lastIndexOf('ji') > 0"></if> 
  • 是否是某个特定字符串,某些业务有此需要。
<if test="username != null and 'hello' == username"></if> 
或者
<if test="username != null and 'hello' eq username"></if>

注意:

<if test="username != null and 'hello' == username"></if>

这种形式的写法在参数类型是字符串的时候是没有问题的,但是参数类型为非字符串类型的时候就需要写成

<if test="username != null and 'hello'.toString() == username.toString()"></if>

mybatis对于字符串的相等不相等的判断也是有对应的特俗操作符

if的条件判断test是支持对象自身方法调用的,即使是自己写的方法

例如:里面可以用‘xxxx’.equals(xxxx) 字符串的比较两个字符串方法

xxxx.indexOf('ss') 判断字符串里面是否包含某个字符等等

  1. 判断list是否为空

if条件判断可以直接调用对象自身的方法进行逻辑判断,所以list判空。可以调用.size()>0或者.isEmpty()

例如:

<if test="userList != null and userList.isEmpty()"></if> 
或者
<if test="userList != null and userList.size()>0"></if>
  1. map参数同同理 取值的话 map.key(map中的key名字)即可

if标签判断数字相等"=="

判断的字段是Integer类型

query类:

public class Query{

    /**
     * 条件
     */
    private Integer a;

}

下面两种都可以:

<select id="countTable" resultType="java.lang.Long">
  select count(*) from table_name 
   <where>
      <if test="a == 3">
            and A = #{a}
      </if>
  </where>
</select> 
<select id="countTable" resultType="java.lang.Long">
  select count(*) from table_name 
   <where>
      <if test="a == '3'.toString()">
            and A = #{a}
      </if>
  </where>
</select> 

判断的字段是String类型

  • 如果这个字段的值是数字,那么和Integer类型是一样的,3 或者 ‘3’.toString() 都可以,但是 ‘3’ 不行
  • 如果这个字段的值不是数字,比如: “y” ,那么就要这样写:‘y’.toString()

query类:

public class Query{

    /**
     * 条件
     */
    private String a;
}

sql:

<select id="countTable" resultType="java.lang.Long">
  select count(*) from table_name 
   <where>
      <if test="a == '3'.toString()">
            and A = #{a}
      </if>
     <if test="a != null and a != '3'.toString()">
            and B = #{a}
     </if>
  </where>
</select> 

trim标签

trim标签语法

<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>

prefix:在trim标签内sql语句加上前缀。
suffix: 在trim标签内sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。
prefixOverrides: 指定去除多余的前缀内容

往购物车表中插入数据的mybatis语句

<insert id="insert" parameterType="com.tortuousroad.groupon.cart.entity.Cart">
        insert into cart
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">
                id,
            </if>
            <if test="userId != null">
                user_id,
            </if>
            <if test="dealId != null">
                deal_id,
            </if>
            <if test="dealSkuId != null">
                deal_sku_id,
            </if>
            <if test="count != null">
                count,
            </if>
            <if test="createTime != null">
                create_time,
            </if>
            <if test="updateTime != null">
                update_time,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">
                #{id,jdbcType=BIGINT},
            </if>
            <if test="userId != null">
                #{userId,jdbcType=BIGINT},
            </if>
            <if test="dealId != null">
                #{dealId,jdbcType=BIGINT},
            </if>
            <if test="dealSkuId != null">
                #{dealSkuId,jdbcType=BIGINT},
            </if>
            <if test="count != null">
                #{count,jdbcType=INTEGER},
            </if>
            <if test="createTime != null">
                #{createTime,jdbcType=TIMESTAMP},
            </if>
            <if test="updateTime != null">
                #{updateTime,jdbcType=TIMESTAMP},
            </if>
        </trim>
    </insert>

没有指定suffixOverrides=","

拼接的sql语句为:

insert into cart (id,user_id,deal_id,) values(1,2,1,);

括号中多了个","符号,语法错误。

指定suffixOverrides=","

拼接的sql语句为:

insert into cart (id,user_id,deal_id,) values(1,2,1);

多余的","被去掉了,语法正确。

参考文章

https://blog.csdn.net/wang_luwei/article/details/122038039

标签:语句,判断,jdbcType,SQL,MyBatis,动态,id
From: https://www.cnblogs.com/xiaoyuzhou55/p/18131245

相关文章

  • mysql修改密码报错:Your password does not satisfy the current policy requirements
    参考https://blog.csdn.net/u013449046/article/details/106455041这是mysql初始化时,使用临时密码,修改自定义密码时,由于自定义密码比较简单,就出现了不符合密码策略的问题。密码策略问题异常信息:ERROR1819(HY000):Yourpassworddoesnotsatisfythecurrentpolicyrequ......
  • MySQL的CDC数据实时同步
    MySQL的CDC数据实时同步 背景近段时间,业务系统架构基本完备,数据层面的建设比较薄弱,因为笔者目前工作重心在于搭建一个小型的数据平台。优先级比较高的一个任务就是需要近实时同步业务系统的数据(包括保存、更新或者软删除)到一个另一个数据源,持久化之前需要清洗数据并且构建一......
  • MySQL数据库下载及安装教程
    MySQL数据库下载及安装教程(最最新版)一、下载mysql数据库二、安装Mysql三、验证是否安装成功(一)、命令提示符cmd窗口验证(二)、MySQL控制台验证一、下载mysql数据库进入MySQL官方网站(https://www.mysql.com/downloads/),按下图顺序点击进入下载页面。 注意:这里MSIInstal......
  • mysql半同步复制
    1、首先在master上面安装插件INSTALLPLUGINrpl_semi_sync_masterSONAME'semisync_master.so';QueryOK,0rowsaffected(0.01sec)2、设置master全局变量和超时时间SETGLOBALrpl_semi_sync_master_enabled=1;QueryOK,0rowsaffected(0.00sec)查看变量是否开......
  • SQL 执行大脚本 提示内存不足 解决办法
    SQL 执行大脚本 提示内存不足 解决办法 用微软自带的sqlcmd工具,可以导入执行。以SQL Server 2008R版本为例:第一步:Win+R 键入:cmd 命令,开启命令行工具;第二步:键入:cd C:\Program Files\Microsoft SQL Server\100\Tools\Binn (具体目录路径跟你安装的SQL位置有关)第三步:键入......
  • 丐版sqlserver AlwaysOn集群
    丐版sqlserver集群之前试过docker的,k8s的,然后发现,还是最朴素的是最简单的,希望有大佬能够汉化,他妈的,那些英文看得人要发癫啊。前置准备,参照丐版pxc集群:https://www.cnblogs.com/zwnfdswww/p/18112077如果不关防火墙:打开对应的端口即可:sudofirewall-cmd--zone=public--a......
  • NL2SQL进阶系列(2):DAIL-SQL、DB-GPT开源应用实践详解Text2SQL
    NL2SQL进阶系列(2):DAIL-SQL、DB-GPT开源应用实践详解[Text2SQL]NL2SQL基础系列(1):业界顶尖排行榜、权威测评数据集及LLM大模型(SpidervsBIRD)全面对比优劣分析[Text2SQL、Text2DSL]NL2SQL基础系列(2):主流大模型与微调方法精选集,Text2SQL经典算法技术回顾七年发展脉络梳理NL2SQL......
  • NL2SQL进阶系列(1):DB-GPT-Hub、SQLcoder、Text2SQL开源应用实践详解
    NL2SQL进阶系列(1):DB-GPT-Hub、SQLcoder、Text2SQL开源应用实践详解NL2SQL基础系列(1):业界顶尖排行榜、权威测评数据集及LLM大模型(SpidervsBIRD)全面对比优劣分析[Text2SQL、Text2DSL]NL2SQL基础系列(2):主流大模型与微调方法精选集,Text2SQL经典算法技术回顾七年发展脉络梳理1.......
  • Mysql中Varchar(50)和varchar(500)区别是什么?
    一.问题描述我们在设计表结构的时候,设计规范里面有一条如下规则:对于可变长度的字段,在满足条件的前提下,尽可能使用较短的变长字段长度。为什么这么规定,我在网上查了一下,主要基于两个方面基于存储空间的考虑基于性能的考虑网上说Varchar(50)和varchar(500)存储空间上是......
  • C#长sql语句换行(长字符串换行且换行符不计入字符串中)
    示例:在红圈处敲回车vs会将其分段并拼接,这不是我想要的效果、不仅不美观还不好复制sql语句只需要在字符串前加一个@号就可以解决......