Mybatis-动态SQL

Mybatis动态SQL Mybatis动态SQL的基本使用 阅读详情
AI摘要

本文围绕Mybatis动态SQL展开,介绍了动态SQL的概念,即SQL语句会随用户输入或外部条件变化。还详细讲解了Mybatis中实现动态SQL的标签,如if用于条件判断拼接SQL,foreach用于遍历集合,sql和include用于抽取和引用重复SQL片段,通过多个案例展示其具体应用。

Mybatis动态SQL

1 什么是动态SQL

在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者2个或者全部。
image.png
image.png
而在我们刚才编写的SQL语句中,我们会看到,我们将三个条件直接写死了。 如果页面只传递了参数姓名name 字段,其他两个字段 性别 和 入职时间没有传递,那么这两个参数的值就是null。
此时,执行的SQL语句为:
image.png
这个查询结果是不正确的。正确的做法应该是:传递了参数,再组装这个查询条件;如果没有传递参数,就不应该组装这个查询条件。
比如:如果姓名输入了"张", 对应的SQL为:
select * from emp where name like ‘%张%’ order by update_time desc;
如果姓名输入了"张",,性别选择了"男",则对应的SQL为:
select * from emp where name like ‘%张%’ and gender = 1 order by update_time desc;
SQL语句会随着用户的输入或外部条件的变化而变化,我们称为:动态SQL。
image.png
在Mybatis中提供了很多实现动态SQL的标签,我们学习Mybatis中的动态SQL就是掌握这些动态SQL标签。

2 动态SQL-if

<if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。

<if test="条件表达式">
   要拼接的sql语句
</if>

接下来,我们就通过<if>标签来改造之前条件查询的案例。

2.1 条件查询

示例:把SQL语句改造为动态SQL方式

  • 原有的SQL语句
<select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        where name like concat('%',#{name},'%')
              and gender = #{gender}
              and entrydate between #{begin} and #{end}
        order by update_time desc
</select>
  • 动态SQL语句
<select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        where
    
             <if test="name != null">
                 name like concat('%',#{name},'%')
             </if>
             <if test="gender != null">
                 and gender = #{gender}
             </if>
             <if test="begin != null and end != null">
                 and entrydate between #{begin} and #{end}
             </if>
    
        order by update_time desc
</select>

测试方法:

@Test
public void testList(){
    //性别数据为null、开始时间和结束时间也为null
    List<Emp> list = empMapper.list("张", null, null, null);
    for(Emp emp : list){
        System.out.println(emp);
    }
}

执行的SQL语句:
image.png
下面呢,我们修改测试方法中的代码,再次进行测试,观察执行情况:

@Test
public void testList(){
    //姓名为null
    List<Emp> list = empMapper.list(null, (short)1, null, null);
    for(Emp emp : list){
        System.out.println(emp);
    }
}

执行结果:
image.png
再次修改测试方法中的代码,再次进行测试:

@Test
public void testList(){
    //传递的数据全部为null
    List<Emp> list = empMapper.list(null, null, null, null);
    for(Emp emp : list){
        System.out.println(emp);
    }
}

执行的SQL语句:
image.png
以上问题的解决方案:使用<where>标签代替SQL语句中的where关键字

  • <where>只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
<select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        <where>
             <!-- if做为where标签的子元素 -->
             <if test="name != null">
                 and name like concat('%',#{name},'%')
             </if>
             <if test="gender != null">
                 and gender = #{gender}
             </if>
             <if test="begin != null and end != null">
                 and entrydate between #{begin} and #{end}
             </if>
        </where>
        order by update_time desc
</select>

测试方法:

@Test
public void testList(){
    //只有性别
    List<Emp> list = empMapper.list(null, (short)1, null, null);
    for(Emp emp : list){
        System.out.println(emp);
    }
}

执行的SQL语句:
image.png

2.2 更新员工

案例:完善更新员工功能,修改为动态更新员工数据信息

  • 动态更新员工信息,如果更新时传递有值,则更新;如果更新时没有传递值,则不更新
  • 解决方案:动态SQL

修改Mapper接口:

@Mapper
public interface EmpMapper {
    //删除@Update注解编写的SQL语句
    //update操作的SQL语句编写在Mapper映射文件中
    public void update(Emp emp);
}

修改Mapper映射文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">

    <!--更新操作-->
    <update id="update">
        update emp
        set
            <if test="username != null">
                username=#{username},
            </if>
            <if test="name != null">
                name=#{name},
            </if>
            <if test="gender != null">
                gender=#{gender},
            </if>
            <if test="image != null">
                image=#{image},
            </if>
            <if test="job != null">
                job=#{job},
            </if>
            <if test="entrydate != null">
                entrydate=#{entrydate},
            </if>
            <if test="deptId != null">
                dept_id=#{deptId},
            </if>
            <if test="updateTime != null">
                update_time=#{updateTime}
            </if>
        where id=#{id}
    </update>

</mapper>

测试方法:

@Test
public void testUpdate2(){
        //要修改的员工信息
        Emp emp = new Emp();
        emp.setId(20);
        emp.setUsername("Tom111");
        emp.setName("汤姆111");

        emp.setUpdateTime(LocalDateTime.now());

        //调用方法,修改员工数据
        empMapper.update(emp);
}

执行的SQL语句:
image.png
再次修改测试方法,观察SQL语句执行情况:

@Test
public void testUpdate2(){
        //要修改的员工信息
        Emp emp = new Emp();
        emp.setId(20);
        emp.setUsername("Tom222");
      
        //调用方法,修改员工数据
        empMapper.update(emp);
}

执行的SQL语句:
image.png
以上问题的解决方案:使用<set>标签代替SQL语句中的set关键字

  • <set>:动态的在SQL语句中插入set关键字,并会删掉额外的逗号。(用于update语句中)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">

    <!--更新操作-->
    <update id="update">
        update emp
        <!-- 使用set标签,代替update语句中的set关键字 -->
        <set>
            <if test="username != null">
                username=#{username},
            </if>
            <if test="name != null">
                name=#{name},
            </if>
            <if test="gender != null">
                gender=#{gender},
            </if>
            <if test="image != null">
                image=#{image},
            </if>
            <if test="job != null">
                job=#{job},
            </if>
            <if test="entrydate != null">
                entrydate=#{entrydate},
            </if>
            <if test="deptId != null">
                dept_id=#{deptId},
            </if>
            <if test="updateTime != null">
                update_time=#{updateTime}
            </if>
        </set>
        where id=#{id}
    </update>
</mapper>

再次执行测试方法,执行的SQL语句:
image.png
小结

  • <if>
    • 用于判断条件是否成立,如果条件为true,则拼接SQL

形式:

  • …
  • <where>
    • where元素只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
  • <set>
    • 动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)

3 动态SQL-foreach

案例:员工删除功能(既支持删除单条记录,又支持批量删除)
image.png
SQL语句:
delete from emp where id in (1,2,3);
Mapper接口:

@Mapper
public interface EmpMapper {
    //批量删除
    public void deleteByIds(List<Integer> ids);
}

XML映射文件:

  • 使用<foreach>遍历deleteByIds方法中传递的参数ids集合
<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每一次遍历使用的分隔符" 
         open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
</foreach>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
    <!--删除操作-->
    <delete id="deleteByIds">
        delete from emp where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
</mapper>

执行的SQL语句:

4 动态SQL-sql&include

问题分析:

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

image.png
image.png
我们可以对重复的代码片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后再通过<include>标签进行引用。

  • <sql>:定义可重用的SQL片段
  • <include>:通过属性refid,指定包含的SQL片段

image.png
SQL片段: 抽取重复的代码

<sql id="commonSelect">
    select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
</sql>

然后通过<include> 标签在原来抽取的地方进行引用。操作如下:

<select id="list" resultType="com.itheima.pojo.Emp">
    <include refid="commonSelect"/>
    <where>
        <if test="name != null">
            name like concat('%',#{name},'%')
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
        </if>
    </where>
    order by update_time desc
</select>
Mybatis学习笔记&注解/xml映射/动态SQL%%%Mybatis教程 JDBC 是使用 Java 语言操作关系型数据库的一套 APIJDBC,全称Java DataBase Connectivity(java数据库连接),是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问。它是由一组用java语言编写的类和接口组成,是sun公司制定的一套接口(interface),接口都有调用者和实现者。JDBC为程序开发人员提供了一组用于实现对数据库访问的JDBCAPI,并支持SQL语言,是sun开发的一套数据库访问编程接口,是一种SQL级的API。 阅读详情

相关推荐

Mybatis动态SQL注解开发操作数据库

在上面的示例中,@SelectProvider注解指定了Provider接口的类型和方法,Provider接口中包含了生成SELECT语句的方法getPersonFromProviderById。常用的注解有@Select,@Update,@Insert,@Delete等,它们分别用于配置查询,更新,插入和删除操作。在这个例子中,@InsertProvider注解指定了Provider接口的类型和方法,Provider接口中包含了生成INSERT语句的方法insertUser。2、编写Mapper接口。

码农从0到1 1075

Mybatis动态SQL(详细介绍)

Mybatis的动态SQL介绍及应用——详细介绍

m0_74777020的博客 1万+

MyBatis的动态SQL

MyBatis的映射文件中支持在基础SQL上添加一些逻辑操作,并动态拼接成完整的SQL之后再执行,以达到SQL复用、简化编程的效果。Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。

2301_77072336的博客 1129

Mybatis--动态SQL

前言if标签if+wheretrim标签choose(when,otherwise)标签foreach标签sql片段 前言 mybatis的动态sql是一种根据特定的条件来进行动态拼接sql语句的字符串问题,动态 SQL 是 MyBatis 的强大特性之一。使用过 JDBC 或其它类似的框架,大家应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。 下面,我就以t_emp表来讲解 if标签 .

梦想也许遥不可及,但重要的是追梦的过程,用博客记录自己的成长,记录自己一步一步向上攀登的印记 5816

MyBatis 动态 SQL

MyBatis动态SQL是在XML映射文件中通过特定标签实现SQL语句动态拼接的技术,解决了传统JDBC手动拼接SQL的繁琐问题。文章介绍了MyBatis的9种动态SQL标签:if(条件判断)、where+if(查询条件处理)、set(更新操作)、choose/when/otherwise(多条件分支)、trim(格式化处理)等,并详细说明了各标签的语法和使用场景。动态SQL通过OGNL表达式实现参数值计算和SQL拼接,既提高了开发效率,又需注意性能优化和SQL注入防范。文中提供了多个典型示例,如条件查询、

阿超的博客 1132

Windows Server下OnlyOffice Workspace社区版安装避坑指南(含局域网邮箱配置)

本文详细介绍了在Windows Server环境下部署OnlyOffice Workspace社区版的完整流程,特别针对企业内网环境中的邮箱配置和端口冲突等常见问题提供了实用解决方案。通过硬件资源配置建议、软件环境检查清单以及内网邮箱系统搭建方案对比,帮助用户高效搭建企业级协作平台,实现团队协作的无缝对接。

weixin_29231263的博客 449

【MyBatis】动态SQL

在前一篇中,我们已经讲解了Mybatis的基本使用,那么本篇我们就进一步来了解Mybatis的功能。本篇我们主要讲的是Mybatis中的动态SQL,在前面我们的学习中,我们编写的SQL语句基本都是固定的,每个参数都需要传递,而通过动态SQL,它能根据我们所给的参数,动态地选择参数,不需要每个都传递。

zhyhgx的博客 2203

FIFO应用于UART串口(含代码)

FIFO(First in first out)即先入先出,可以把它理解成一个缓存器,对于收发两端速度不一致,位宽不一致的情况可以使用FIFO作为收发两端中间的“调节剂”使数据可以进行正常发送。

m0_58544042的博客 2753

Mybatis之动态SQL

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。 利用动态 SQL 这一特性可以彻底摆脱这种痛苦。 虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQ...

JustinNeil的博客 1万+

在LinuxMint 22.1(Ubuntu24.04)上安装使用同花顺远航版

Linux用户成功在LinuxMint22.1系统上通过Wine9.0运行同花顺远航版,解决了长期困扰的股票行情软件问题。此前Linux原生版同花顺功能简陋且停止更新,Wine版通达信存在显示问题。作者作为自由软件支持者,通过调整Wine配置文件解决了高分屏显示异常问题,实现了远航版的正常使用。期待同花顺能重启Linux原生版开发,支持更多处理器架构,完善国产软件生态。该方案为Linux股票软件用户提供了实用参考。

5140

vue3 - vite报错TypeError: crypto.hash is not a function(vue3+vite启动运行提示错误,项目无法启动且打包报错失败,详细解决排查方案教程)

vue3 vite 报错,vue3+vite启动报错:TypeError: crypto.hash is not a function,创建vue3+vite项目时报错TypeError: crypto.hash is not a function,如何解决这个问题,VUE3+VITE报错crypto.hash,vue3运行报错,vite运行报错,vue3打包报错,vite打包报错,vue3新建项目无法运行,vue3 vite创建项目直接报错了,node版本不兼容,修改了node版本还是不行,依旧报错,一直

✅ 精选推荐文章 1万+

mybatis强大的动态SQL

我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。:抽取 SQL 语句标签。:引入 SQL 片段标签。抽取的 SQL 语句三、多条件组合查询之<where-if>我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。:条件标签。如果有动态条件,则使用该标签代替 where 关键字。:条件判断标签。查询条件拼接。

2501_90401192的博客 1637

RT-DETR改进策略【独家融合改进】| HTB + GFPN + LGAG

解决现有Transformer方法的局限:现有的基于Transformer的方法在处理恶劣天气图像恢复时,为了提高内存利用效率,通常将自注意力操作限制在固定的空间范围或仅仅在通道维度上,这种限制阻碍了Transformer对长距离空间特征的捕捉能力,从而影响了图像恢复的性能。利用天气退化特征:观察到天气引起的退化因素主要导致相似的遮挡和亮度变化,因此希望设计一种能够更好地处理这些特征的模块。

Limiiiing的博客 199

MyBatis 动态SQL详解

注意,``失败后, `` 关键字只会去掉库表字段赋值前面的and,不会去掉语句后面的and关键字,即注意,`` 只会去掉`` 语句中的最开始的and关键字。在实际开发中会遇到许多相同的SQL,比如根据某个条件筛选,这个筛选很多地方都能用到,我们可以将其抽取出来成为一个公用的部分,这样修改也方便,一旦出现了错误,只需要改这一处便能处处生效了,此时就用到了这个标签了。这个标签和是天仙配,是共生的,include用于引用sql标签定义的常量。

Coisini__S的博客 1268

ABAP Cloud 里的高性能日志:CL_BALI_LOG、XCO_CP_BAL 与 AML 的性能对比与选型指南

ABAP日志框架性能对比与选型建议 本文对比了ABAP Cloud中三种主流日志框架的性能表现与适用场景: 标准BALI:适合明确需要保存日志的场景,保存路径短,性能较好 XCO_CP_BAL:API更现代但性能较低,适合需要即时可见性的场景 AML:开源框架,擅长消息缓冲,适合批量处理时暂存消息 测试结果表明: 纯记录不落库时AML最快 需要保存时BALI性能最优 second connection不提升性能但能确保日志留存 选型建议: 高频批处理优先AML+BALI组合 故障诊断考虑XCO的即时可见性

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 215

【WRF-Urban】URBPARM_LCZ.TBL 查找表解释及内容

URBPARM_LCZ.TBL 查找表解释及内容

WW、forever的博客 1754

MyBatis 之 动态 SQL

动态 SQL

lfm1010123的博客 2134

dToF直方图之美_deadtime死区时间

IMX459的死区时间可以在6ns,这个时间是什么级别,车载激光雷达激光器的光脉宽一般都在4ns以上,也就是这个时间贴近去SPAD的死区时间,这就导致了pile up会非常弱,不会有太多数量的光子计数堆积,加上某些SPAD设计,对TDC有一些更深入的考量,所以不需要去校正pile up算法。Sensor层面决定了pile up的复杂程度,如果一个dToF的SPAD一致性非常好,那么pile up校正可以简单到极致,也就是一句代码的事,比如IMX611,优秀到不需要后端去考虑校正pile up。

dream it possible 1436

Mybatis的动态SQL

Test public void insertMoreByList(){ User user1 = new User("a1","男","北京");

m0_73971785的博客 1275

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【MyBatis】动态 SQL

这些标签可以根据传入的参数动态地添加、删除或修改 SQL 语句的某些部分。语句,用来根据不同条件选择执行不同的 SQL 语句,包含。标签根据传入的条件判断是否包含该 SQL 片段。用于在 SQL 语句中循环处理集合或数组,常用于。文件中使用特定的标签来完成的。子句中的值,并且自动加上括号和逗号分隔符。,则将相应的条件添加到 SQL 查询中。是指在程序执行过程中,根据实际的情况。标签用于自动处理 SQL 语句中的。部分,避免了多余的逗号和条件。部分,它会自动去除多余的。,之后的条件会自动处理为。

weixin_63466958的博客 1363

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

MyBatis 动态 SQL 最全教程

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

2501_92608043的博客 1073

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

MyBatis之动态sql

resultType适用于简单的结果映射,可以自动进行映射;resultMap适用于复杂的结果映射,需要手动定义映射关系。

kissship的博客 2634
上一篇: Mybatis入门及基本操作
下一篇: JavaScript对象
actavy
博客等级 码龄4年 315粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值