首页 > 数据库 >Mybatis中的动态 SQL

Mybatis中的动态 SQL

时间:2023-05-04 17:57:00浏览次数:37  
标签:语句 username sql sex SQL Mybatis 动态 where

一、MyBatis动态 sql 是什么?

1.动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。

2.动态SQL:code that is executed dynamically。 它一般是根据用户输入或外部条件动态组合的SQL语句块。 动态SQL能灵活的发挥SQL强大的功能、方便的解决一些其它方法难以解决的问题。 相信使用过动态SQL的人都能体会到它带来的便利,然而动态SQL有时候在执行性能 (效率)上面不如静态SQL,而且使用不恰当,往往会在安全方面存在隐患 (SQL 注入式攻击)。

(1)Mybatis 动态 sql 是做什么的?

Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。

(2)动态 sql 的执行原理?

  原理为:使用OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

  OGNL (Object Graph Navigation Language) 是一个开源的表达式引擎。通过使用OGNL,我们能够通过表达式存取Java对象树中的任意属性和调用Java对象树的方法等。

二、Mybatis 的 9 种 动 态 sql 标 签有哪些?

元素 作用 备注
if 判断语句 单条件分支判断
choose(when、otherwise) 相当于 Java 中的 switch case 语句 多条件分支判断
trim,where 辅助元素 用于处理一些SQL拼装问题
foreach 循环语句 在in语句等列举条件常用
bind 辅助元素 拼接参数

if标签:条件判断

MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。

不使用动态sql

<select id="selectUserByUsernameAndSex"
        resultType="user" parameterType="com.ys.po.User">
    <!-- 这里和普通的sql 查询语句差不多,对于只有一个参数,后面的 #{id}表示占位符,里面          不一定要写id,
         写啥都可以,但是不要空着,如果有多个参数则必须写pojo类里面的属性 -->
    select * from user where username=#{username} and sex=#{sex}
</select>

if 语句使用方法简单,常常与 test 属性联合使用。语法如下。

<if test="判断条件">    SQL语句</if>
<select id="selectAllWebsite" resultMap="myResult">
  select id,name,url from website
  where 1=1
  <if test="name != null">
    AND name like #{name}
  </if>
  <if test="url!= null">
    AND url like #{url}
  </if>
</select>

上面的查询语句,我们可以发现,如果 #{username} 为空,那么查询结果也是空,如何解决这个问题呢?使用 if 来判断,可多个 if 语句同时使用。以下语句表示为可以按照网站名称(name)或者网址(url)进行模糊查询。如果您不输入名称或网址,则返回所有的网站记录。但是,如果你传递了任意一个参数,它就会返回与给定参数相匹配的记录。

2.where+if标签

  where、if同时使用可以进行查询、模糊查询。注意,where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

      <select id="findQuery" resultType="Student">
            <include refid="selectvp"/>
            <where>
                <if test="sacc != null">
                    sacc like concat('%' #{sacc} '%')
                </if>
                <if test="sname != null">
                    AND sname like concat('%' #{sname} '%')
                </if>
                <if test="sex != null">
                    AND sex=#{sex}
                </if>
                    AND phone=#{phone}
            </where>
        </select>

 3.set标签

set可以用来修改

<update id="upd">
        update student
        <set>
            <if test="sname != null">sname=#{sname},</if>
            <if test="spwd != null">spwd=#{spwd},</if>
            <if test="sex != null">sex=#{sex},</if>
            <if test="phone != null">phone=#{phone}</if>
        sid=#{sid}
        </set>
        where sid=#{sid}
</update>

4.choose(when,otherwise) 语句

  有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句。

<select id="selectUserByChoose" resultType="com.ys.po.User" parameterType="com.ys.po.User">
      select * from user
      <where>
          <choose>
              <when test="id !='' and id != null">
                  id=#{id}
              </when>
              <when test="username !='' and username != null">
                  and username=#{username}
              </when>
              <otherwise>
                  and sex=#{sex}
              </otherwise>
          </choose>
      </where>
</select>

 也就是说,这里我们有三个条件,id,username,sex,只能选择一个作为查询条件

 如果 id 不为空,那么查询语句为:select * from user where id=?

 如果 id 为空,那么看username 是否为空,如果不为空,那么语句为 select * from user where username=?;

 如果 username 为空,那么查询语句为 select * from user where sex=?

5.trim

   trim标记是一个格式化的标记,可以完成set或者是where标记的功能。

   ①、用 trim 改写上面第二点的 if+where 语句

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">
        select * from user
        <!-- <where>
            <if test="username != null">
               username=#{username}
            </if>
             
            <if test="username != null">
               and sex=#{sex}
            </if>
        </where>  -->
        <trim prefix="where" prefixOverrides="and | or">
            <if test="username != null">
               and username=#{username}
            </if>
            <if test="sex != null">
               and sex=#{sex}
            </if>
        </trim>
</select>

prefix:前缀      

prefixoverride:去掉第一个and或者是or

②、用 trim 改写上面第三点的 if+set 语句

    <update id="updateUserById" parameterType="com.ys.po.User">
        update user u
            <!-- <set>
                <if test="username != null and username != ''">
                    u.username = #{username},
                </if>
                <if test="sex != null and sex != ''">
                    u.sex = #{sex}
                </if>
            </set> -->
            <trim prefix="set" suffixOverrides=",">
                <if test="username != null and username != ''">
                    u.username = #{username},
                </if>
                <if test="sex != null and sex != ''">
                    u.sex = #{sex},
                </if>
            </trim>
         
         where id=#{id}
    </update>

  suffixoverride:去掉最后一个逗号(也可以是其他的标记,就像是上面前缀中的and一样)

6.MyBatis foreach标签

foreach是用来对集合的遍历,这个和Java中的功能很类似。通常处理SQL中的in语句。

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符

你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

//批量查询
<select id="findAll" resultType="Student" parameterType="Integer">
    <include refid="selectvp"/> WHERE sid in
    <foreach item="ids" collection="array"  open="(" separator="," close=")">
        #{ids}
    </foreach>
</select>
//批量删除
<delete id="del"  parameterType="Integer">
    delete  from  student  where  sid in
    <foreach item="ids" collection="array"  open="(" separator="," close=")">
        #{ids}
</foreach> 

标签:语句,username,sql,sex,SQL,Mybatis,动态,where
From: https://www.cnblogs.com/helloworldcode/p/17372051.html

相关文章

  • SQL Server 修改自增列的标识值
    DBCCCHECKIDENT检查指定表中当前标识值,如有必要,则更改标识值。123456DBCCCHECKIDENT   (      table_name         [,{NORESEED|{RESEED[,new_reseed_value]}}] ) [ WITH NO_INFOMSGS]    参数:tab......
  • 5、MySQL的SQL语言、数据库管理、数据类型及DQL的单、多表查询
    进入mysql后,使用help列出的是客户端的命令,使用helpcontents列出服务端命令SQL语句分类(DDLDMLDQL要记住)前三个重要(DDL、DML、DQL、DCL、TCL)DDL:DataDefinationLanguage数据定义语言CREATE,DROP,ALTER(对数据库、表、视图、索引进行创建、删除和更改的工具ALTER改格式)......
  • MySQL事务
    前序原文链接1:https://cloud.tencent.com/developer/article/1899373MySQL有9种存储引擎,不同的引擎,适合不同的场景,常用引擎为InnoDB,它是MySQL的默认存储引擎。登录MySQL,执行showengines可以查询MySQL支持的存储引擎,如图示:1、InnoDB引擎(1)它事务型数据库的首选引擎,支持事务安全表(AC......
  • PostgreSQL 生成随机整数
    首先random()函数用于生成0-1之间的随机数postgres=#SELECTrandom()asrand;rand--------------------0.6296923727161818(1row)取整函数有ceil()floor()trunc()postgres=#SELECTceil(1.5)asceil,floor(1.5)asfloor,trunc(1.5)astrunc;ceil|fl......
  • docker mysql 容器自动停止 -- docker update
    原因:mysql容器占用资源过高被系统杀死解决方法dockerupdate-m500M--memory-reservation500M--memory-swap1000M容器id/容器名说明-m限制内存最大值--memory-reservation是弹性控制内存大小,防止损失性能,建议要开。当宿主机资源充足时,允许容器尽量多地使......
  • PostgreSQL 12 文档: 部分 I. 教程
    部分 I. 教程欢迎来到PostgreSQL教程。下面的几章将为那些新接触PostgreSQL、关系数据库概念和SQL语言的读者给出一个简单介绍。我们只假定读者拥有关于如何使用计算机的一般知识。读者不需要特殊的Unix或编程经验。这一部分主要希望给你一些关于PostgreSQL系统的重要方面......
  • PHP基础--mysqli的事务处理
    <?php//在命令行中:默认创建的表类型为MyISAM表类型,是不支持事务的//在命令行中建表时添加type=InnoDB,默认自动提交事务autocommit,不能回滚//创建连接对象$mysqlConn=newmysqli("localhost","root","root","test");if($error=$mysqli->connect_error){die("......
  • 通常SQL调优过程
    观察,至少跑1天,看看生产的慢SQL情况。开启慢查询日志,设置阙值,比如超过5秒钟的就是慢SQL,并将它抓取出来。explain+慢SQL分析。showprofile。运维经理orDBA,进行SQL数据库服务器的参数调优。总结:1、慢查询的开启并捕获2、explain+慢SQL分析3、showprofile查询SQL在M......
  • mysql - shell 执行 sql 文件有中文乱码-解决
    1.背景执行  发现部分中文乱码2.解决在执行sql语句之前,加入下面指令即可SETNAMESutf8mb4;SETFOREIGN_KEY_CHECKS=0; ......
  • 学习使用benchmarksql压测数据库
    介绍benchmarksql是一款符合TPC-C基准压力测试工具,TPC-C是衡量在线事务处理的基准。TPC-C模型是模拟一个商品批发公司的销售模型,这个模型涵盖了一个批发公司面向客户对一系列商品进行销售的过程,这包括管理订单,管理库存,管理账号收支等操作。这些操作涉及到仓库、商品、客户、订单......