MyBatis 操作数据库(构造动态 SQL)

前言

        动态 SQL 是 Mybatis 的强⼤特性之⼀,能够完成不同条件下不同的 sql 拼接。

<if> 标签

        我们在填写用户信息的时候经常会看到如下的界面,用户信息中包含必填信息和非必填信息,非必填信息是填和不填都可以的,那这样的话插入到数据库中的数据有多种情况,SQL 语句也有多种情况,比如地址管理,我可以选择填,也可以选择不填,那么 SQL 语句的插入语句就要对应插入或者不插入

        要想完成这个效果,我们就需要构造动态 SQL

接口定义:

//通过用户提供的数据,动态构造 SQL 语句进行插入
Integer insertUserByCondition(UserInfo userInfo);

Mapper.xml实现:

<insert id="insertUserByCondition">insert into userinfo<trim prefix="(" suffix=")" suffixOverrides=","><if test="username!=null">username,</if><if test="password!=null">password,</if><if test="age!=null">age,</if><if test="gender!=null">gender,</if><if test="phone!=null">phone</if></trim>values<trim prefix="(" suffix=")" suffixOverrides=","><if test="username!=null">#{username},</if><if test="password!=null">#{password},</if><if test="age!=null">#{age},</if><if test="gender!=null">#{gender},</if><if test="phone!=null">#{phone}</if></trim></insert>

         <if> 标签的 test 属性表示判断的内容,如下的代码,判断参数 username 的值是否为 null,相当于判断用户是否输入 username,如果不为 null,说明用户输入了 username ,就需要插入数据到 username 字段,所以拼接 username, 到 SQL 语句中

<if test="username!=null">username,
</if>

        如果所有的参数都赋了值,构造的 SQL 语句就是:

insert into userinfo( username, password, age, gender, phone )
values(#{username},#{password},#{age},#{gender},#{phone});

        如果参数 gender 和 phone 都没赋值,就是:

insert into userinfo( username, password, age)
values(#{username},#{password},#{age});

        构造的 SQL 语句是根据用户的输入动态改变的

<trim> 标签

        在上面 Mapper.xml 实现的代码中,我们用到了 <trim>  标签

标签中有如下属性:

• prefix:表⽰整个语句块,以prefix的值作为前缀 

• suffix:表⽰整个语句块,以suffix的值作为后缀

• prefixOverrides:表⽰整个语句块要去除掉的前缀

• suffixOverrides:表⽰整个语句块要去除掉的后缀

       在上面 Mapper.xml 实现的代码中,我们使用了<trim> 标签进行了以下处理

• 基于 prefix 配置,开始部分加上 ( 

• 基于suffix 配置,结束部分加上 )

 • 多个组织的语句都以 ,  结尾,在最后拼接好的字符串还会以 ,  结尾,会基于 suffixOverrides 配置去掉最后⼀个 ,  

<where> 标签

        <where> 标签只会在⼦元素有内容的情况下才插⼊where⼦句,⽽且会⾃动去除⼦句的开头的 AND 或 OR

        看下⾯这个场景, 系统会根据我们的筛选条件, 动态组装 select 语句的 where 条件,来查询到我们指定的内容

        假设所有的参数都输入,我们得到的 SQL 语句如下:

SELECT id,username,password,age,gender,phone,delete_flag,create_time,update_time 
FROM userinfo 
WHERE id = #{id}
AND username = #{username} 
AND gender = #{gender};

        接口定义:

 //通过用户提供的数据,动态构造 SQL 语句进行查询
List<UserInfo> selectByCondition(UserInfo userInfo);

        Mapper.xml实现:

    <select id="selectByCondition" resultType="com.example.springbootdemo.dao.UserInfo">select id,username,password,age,gender,phone,delete_flag,create_time,update_timefrom userinfo<where><if test="id!=null">and id=#{id}</if><if test="username!=null">and username=#{username}</if><if test="gender!=null">and gender=#{gender}</if></where></select>

        假设用户一个参数都没有输入,得到的 SQL 语句就是:

select id,username,password,age,gender,phone,delete_flag,create_time,update_time
from userinfo;

        假设用户没有输入 id 参数,得到的 SQL 语句就是:

SELECT id,username,password,age,gender,phone,delete_flag,create_time,update_time 
FROM userinfo 
WHERE username = #{username} 
AND gender = #{gender};

<set>标签

         <set>标签动态的在SQL语句中插⼊set关键字,并会删掉额外的逗号.(⽤于update语句中)

        根据用户传入的参数,动态构造 SQL 语句,插入相关内容

        接⼝定义:根据传⼊的用户 id 属性,修改其他传入参数的属性

//通过用户提供的数据,动态构造 SQL 语句进行修改
Integer updateByCondition(UserInfo userInfo);

        Mapper.xml实现:

    <update id="updateByCondition">update userinfo<set><if test="username!=null">username=#{username},</if><if test="age!=null">age=#{age},</if><if test="deleteFlag!=null">delete_flag=#{deleteFlag}</if></set>where id=#{id}</update>

<foreach> 标签

对集合进⾏遍历时可以使⽤该标签。

标签有如下属性:

• collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象

• item:遍历时的每⼀个对象 

• open:语句块开头的字符串 

• close:语句块结束的字符串 

• separator:每次遍历之间间隔的字符串

        有以下场景我们将要删除的用户 id 都集中放到一个 List<Integer> 列表当中,在删除的时候,将列表中的用户 id 所指向的信息都进行删除

        假设列表当中的数据为{1,2,3,4,5},我们要构造的 SQL 语句就应该为:

delete from userinfo where id in(1,2,3,4,5);

        接口定义:

//给定一个 id 集合,将集合中的所有 id 对应的用户数据都删除
Integer deleteByIds(List<Integer> ids);

        Mapper.xml实现:

    <delete id="deleteByIds">delete from userinfowhere id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach></delete>

       根据一开始提到的例子,我们通过 <foreach> 标签要构造出来的 SQL 结构应该为 (1,2,3,4,5),1,2,3,4,5 要通过遍历集合中的内容获得、

collection="ids" 表示绑定了参数中的集合 ids 

item="id" 表示遍历集合得到的数据放到 id 中,通过 id 来使用

separator=","  遍历集合得到的数据之间通过  , 进行分割

open="("  <foreach> 标签包含的语句块以 "(" 作为开头

close=")"  <foreach> 标签包含的语句块以 ")" 作为结尾

<sql> 和 <include> 标签

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

        我们可以通过 <sql> 标签提取重复的 SQL 片段进行封装,通过 <include> 标签引用封装好的 SQL 片段

        通过 <sql> 标签封装:

        通过 id 属性为封装的 SQL 片段命名,方便后续进行调用

<sql id="allColumn">id,username,password,age,gender,phone,delete_flag,create_time,update_time
</sql>

        通过 <include> 标签引用:

        通过 refid 属性设置要引入的 SQL 片段

    <select id="selectByCondition2" resultType="com.example.springbootdemo.dao.UserInfo">select <include refid="allColumn"></include>from userinfo</select>

         最终得到的 SQL 语句为:

select id,username,password,age,gender,phone,delete_flag,create_time,update_time
from userinfo;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/150223.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基本算法:二分

文章目录 1、整数集合上的二分2、实数域上的二分3、三分求单峰函数极值4、二分答案转化为判定二分的基础用法是在单调序列或单调函数中进行查找。因此,当问题的答案具有单调性时,就可以通过二分把求解转化为判定(根据复杂度理论,判定的难度小于求解),这使得二分的运用范围…

IDEA常用插件合集

功能类&#xff1a; 1、Background Image Plus 换壁纸 2、Chinese(Simplified)... 中文语言包 3、Translation 代码翻译 4、Key Promoter X 快捷键提示插件 5、Rainbow bracket 彩虹括号插件&#xff0c;对于多组括号使用不同的颜色标注 6、Code Glance 代码小地图&a…

参加了南京 GDG 活动:这些精彩的技术讨论,值得与你分享~

一直以来发的文章大都是技术的&#xff0c;这次和大家聊点简单点的。 密集输出这几年&#xff0c;因为疫情没能在线下和大家碰面&#xff0c;去年又因为时间原因浪费了 Google IO China 门票。所以&#xff0c;今年的南京本地的 GDG DevFest 2023 活动一经上线&#xff0c;就报…

国际物流社交销售玩法拆解(三):打造社交电商式分销增长

这一篇&#xff0c;是国际物流行业社交销售玩法最后一篇&#xff0c;也是国际物流企业实现业务经营新增长、打造分销增长体系的新模式。以下&#xff0c;我们一起来拆解这一模式具体内容吧。 #01 国际物流第二曲线&#xff1a;社交电商 经营增长是企业的永恒话题。在客户成本…

C++多线程编程(3):接收线程处理函数的返回值

文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 文章目录 处理带返回值的函数asyncpackaged_taskpromise 处理带返回值的函数 有三种方法&#xff1a; asyncpackaged_taskpromise async 第一种方法是使用 async 函数。 步骤&#xff1a; 使用 async 创建线程处理函…

16. @PostConstruct注解和开关原理(验证码开关、IP开关)

1►PostConstruct注解 PostConstruct是java自带的注解&#xff0c;会在java项目启动的时候先执行下面的方法 2►开关原理&#xff08;验证码开关&#xff09; 我们的项目具有验证码功能&#xff0c;旧版不支持关闭&#xff0c;新版已经支持关闭了。 我们打开页面“参数管…

Python Web APP在宝塔发布

本地测试运行&#xff1a;uvicorn main:app --host 127.0.0.1 --port 8082 --reload 宝塔发布&#xff1a; 运行配置——>启动模式&#xff1a;worker_class uvicorn.workers.UvicornWorker

【STL】:反向迭代器

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关反向迭代器的模拟实现&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通…

rabbitMQ的direct模式的生产者与消费者使用案例

消费者C1的RoutingKey 规则按照info warn 两种RoutingKey匹配 绑定队列console package com.esint.rabbitmq.work03;import com.esint.rabbitmq.RabbitMQUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.DeliverCallback;/*** 消费者01的消息接受*/ p…

如何使用MybatisPlus进行数据分页显示

如何使用MybatisPlus进行数据的分页呢&#xff1f; 使用Mybatis Plus提供的分页插件来简化开发&#xff0c;在MybatisPlusInterceptor的拦截器中添加自动分页的PaginationInnerInterceptor拦截器&#xff0c;当前配置需要交给spring的bean管理&#xff0c;类上添加注解Configu…

目标检测 Faster RCNN全面解读复现

Faster RCNN 解读 经过R-CNN和Fast RCNN的积淀&#xff0c;Ross B. Girshick在2016年提出了新的Faster RCNN&#xff0c;在结构上&#xff0c;Faster RCNN已经将特征抽取(feature extraction)&#xff0c;proposal提取&#xff0c;bounding box regression(rect refine)&…

php聊天室通讯系统常用的接口对接函数 curl、file_get_contents()、WebSocket、消息队列

方法有&#xff1a; 1、HTTP请求&#xff0c;可以通过PHP的curl库或者file_get_contents()函数发送HTTP请求来与聊天室接口进行通信&#xff1b; 2、WebSocket协议&#xff0c;可以使用PHP的WebSocket库或者第三方库来与聊天室接口进行对接&#xff1b; 3、使用这些SDK或者包装…

GIT提交代码

1、从远端克隆master分支 git clone -b master ssh://git*** 2、创建开发分支 git checkout -b 209192_dev 3、在对应分支下更新代码 -f为强制更新&#xff0c;会覆盖本地 git pull -f origin 209192_dev:209192_dev git pull -f origin sit:sit git pull -f origin uat:uat 4、…

Nginx快速入门教程,域名转发、负载均衡

1.Nginx简介 Nginx是⽬前最流⾏的Web服务器&#xff0c; 最开始是由⼀个叫做igor的俄罗斯的程序员开发的&#xff0c; 2019年3⽉11⽇被美国的F5公司以6.7亿美元的价格收购&#xff0c; 现在Nginx是F5公司旗下的⼀款产品了。 2.Nginx的版本 Nginx开源版本主要分为两种&#x…

21、嵌套路由实战操作

1、创建内嵌子路由&#xff0c;你需要添加一个vue文件&#xff0c;同时添加一个与该文件同名的目录用来存放子视图组件。 2、在父组件&#xff08;.vue&#xff09;内增加用于显示子视图内容 新建文件 pages\index_id.vue 生成的对应路由 {path: "/",component: _…

电子病历编辑器源码(Springboot+原生HTML)

一、系统简介 本系统主要面向医院医生、护士&#xff0c;提供对住院病人的电子病历书写、保存、修改、打印等功能。本系统基于云端SaaS服务方式&#xff0c;通过浏览器方式访问和使用系统功能&#xff0c;提供电子病历在线制作、管理和使用的一体化电子病历解决方案&#xff0c…

产品经理不得不知道的电商API接口对接流程梳理

接口对接流程梳理 产品经理 知晓自己负责系统做什么&#xff0c;外接三方系统做什么。 系统对接产品经理实操步骤&#xff1a; ①与公司业务人员沟通&#xff0c;与系统对接方产品/技术描述业务场景&#xff0c;沟通发放接口文档材料 ②拿到材料之后电商API接口过多请对方…

武汉站--ChatGPT/GPT4科研技术应用与AI绘图及论文高效写作

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

麒麟KYLINOS2303系统上禁用新功能介绍页面

原文链接&#xff1a;麒麟KYLINOS2303系统上禁用新功能介绍页面 hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇在麒麟KYLINOS2303系统上禁用新功能介绍页面的文章&#xff0c;在我们安装完系统登录后&#xff0c;会发现有新功能介绍这个界面&#xff0c;我们可以通…

《微信小程序开发从入门到实战》学习十六

第三章 开发第一个小程序 3.3 开发创建投票页面 3.3.2 修改模拟器中的启动页面 通过页面跳转的方式预览第二个页面内容不方便。 微信开发工具的工具栏有一个编译模式的设置&#xff1a; 选择“添加编译模式”&#xff0c; 加一个便于区分的名称&#xff0c;点击确定。 模拟…