MyBatis的强大特性--动态SQL

目录

前言 

if 

trim

where

set 

foreach


前言 

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

        例如在注册用户的时候, 提交的表单中肯定有非必填字段, 前端会将拿到的数据送给后端, 但是, 用户在提交的时候, 由于存在非必填字段, 于是用户提交的字段可能是变数, 可能是一个, 两个或者三个, 例如有下面三个字段

  • username
  • password
  • tele
  • age(非必填)
  • sex
  • .....

        除了age都为必填, 这个时候, 前端返回数据给后端, 然后使用sql将其存入数据库, 那么, 在插入的时候

insert into table(username, password, tele, sex, age) values(#{username},#{username}, #{tele}, #{sex}, #{age});

       上面是age传入的时候, 那么试想一下, 如果这个age如果用户没有选择填写呢, 那么insert语句中的age选项就应该被抹除

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

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

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

if 

    <insert id="insert" parameterType="org.example.model.User" useGeneratedKeys="true" keyProperty="id">insert into user(username,password,nickname,<if test="sex != null">sex,</if>birthday,head) values (#{username},#{password},#{nickname},<if test="sex != null">#{sex},</if>#{birthday},#{head})</insert>

        if中有一个test属性, test是判断这个sex项是否存在的标准, 前端传过来的数据会被解析为java对象, 并将属性写入到对象中, 如果对象中的sex属性为空, 那么就代表用户没有传入这个字段, 于是就需要将这个项给抹除.

trim

        上面的情况是只有一个选填项, 但是如果所有的字段, 都可能是选填项, 那么就可以配合trim使用if来解决:

    <insert id="insert" parameterType="org.example.model.User" useGeneratedKeys="true" keyProperty="id">insert into user<trim prefix="(" suffix=")" suffixOverrides=","><if test="username != null">username,</if><if test="password != null">password,</if><if test="nickname != null">nickname,</if><if test="sex != null">sex,</if><if test="birthday != null">birthday,</if><if test="head != null">head,</if><if test="createTime != null">create_time,</if></trim><trim prefix="values (" suffix=")" suffixOverrides=","><if test="username != null">#{username},</if><if test="password != null">#{password},</if><if test="nickname != null">#{nickname},</if><if test="sex != null">#{sex},</if><if test="birthday != null">#{birthday},</if><if test="head != null">#{head},</if><if test="createTime != null">#{createTime},</if></trim></insert>

 

  • prefix : 表示整个trim语句块的开头
  • suffix : 表示整个trim语句块的结尾
  • prefixOverrides : 表示整个语句块要去除掉的前缀
  • suffixOverrides : 表示整个语句块中, 要去除掉的后缀, 这个后缀是不计suffix的. 例如trim语句块如下, 那么结束的时候就为 " .... .... head, create_time,)" ,呢么就会忽略 ')', 去除create_time后面的','
    <if test="head != null">
    head,
    </if>
    <if test="createTime != null">
    create_time,
    </if>

上面语句翻译过来就是

isnert into user(username, password, age, sex, ) values(#{username}, #{password}, #{age}, #{sex},)

 

        需要注意的是, 这里的sex可能为选填, 无论如何, 这个table_name后面的参数和values中的参数, 必定有以 ',' 结尾的内容, 但是这个在sql中是错误语句. 于是使用suffixOverrides将后缀','去除(不包括 suffix =')').

where

        传⼊的⽤户对象,根据属性做 where 条件查询,⽤户对象中属性不为 null 的,都为查询条件。如user.username 为 "a",则查询条件为 where username="a":
UserMapper 接⼝中新增条件查询⽅法:

List<User> selectByCondition(User user);

xml中新增查询语句:

    <select id="selectByCondition" parameterType="org.example.model.User" resultMap="BaseResultMap">select id, username, password, nickname, sex, birthday, head, create_timefrom user<where><if test="username != null">and username=#{username}</if><if test="password != null">and password=#{password}</if><if test="nickname != null">and nickname=#{nickname}</if><if test="sex != null">and sex=#{sex}</if><if test="birthday != null">and birthday=#{birthday}</if><if test="head != null">and head=#{head}</if><if test="createTime != null">and create_time=#{createTime}</if></where></select>

        注意: 这里的and一定要写到 column = #{column } 的前面, 也就是:

' and column = #{column } '

        where标签就会自动识别并去除多余的and. 

        当然, where也可以使用trim标签和if标签代替.

set 

        根据传⼊的⽤户对象属性来更新⽤户数据,可以使⽤<set>标签来指定动态内容
定义mapper接口:

int updateById(User user);

xml:

    <update id="updateById" parameterType="org.example.model.User">update user<set><if test="username != null">username=#{username},</if><if test="password != null">password=#{password},</if><if test="nickname != null">nickname=#{nickname},</if><if test="sex != null">sex=#{sex},</if><if test="birthday != null">birthday=#{birthday},</if><if test="head != null">head=#{head},</if><if test="createTime != null">create_time=#{createTime},</if></set>where id=#{id}</update>

        set会自动去掉末尾的 ','

foreach

        对集合进⾏遍历时可以使⽤该标签。<foreach>标签有如下属性:

  • collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
  • item:遍历时的每⼀个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串

 示例:根据多个⽂章 id 来删除⽂章数据

ArticleMapper 中新增接⼝⽅法

int deleteByIds(List<Integer> ids);

        使用List接收, Integer为泛型, 传入的是一个Integer的list集合, 每一个Integer对象对应一个要被删除的文章(Article)

ArticleMapper.xml 中新增删除 sql:

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

in后面其实是可以使用一个多表查询的, 现在这里使用的foreach进行遍历.

  • Collection指明集合的类型
  • itme表示每个每一个对象

然后就遍历成了:

delete from article where id in  (item1, item2, item3 ..... )

这一个个item对象就是list中的Integer对象. 也就是对应的int类型, 与id的类型对应. 



 

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

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

相关文章

File类

File 概述 File: 路径 IO流: 传输 路径 相对路径, 绝对路径 File File对象就表示一个路径&#xff0c;可以是文件的路径、也可以是文件夹的路径这个路径可以是存在的&#xff0c;也允许是不存在的 构造方法 代码示例: package FileTest1;import java.io.File;public c…

1+X网络系统建设与运维练习题

1.OSPF的最优路由&#xff0c;会放到IP路由表中指导数据转发 &#xff08;x&#xff09; 2.当AP工作在2.4GHz频段的时候&#xff0c;AP工作的频率范围是2.4GHz~2.4835GHZ。在此频率范围内又划分出14个信道。每信道的中心频率相隔5MHz&#xff0c;每个信道可供占用的带宽为22MHz…

虚幻学习笔记1—给UI添加动画

一、前言 本文所使用的虚幻版本为5.3.2&#xff0c;之前工作都是用unity&#xff0c;做这类效果用的最多的是一个DoTween的插件&#xff0c;在虚幻中都内置集成了这这种效果制作。 图1.1 UI动画 二、过程 1、首先&#xff0c;在诸如按钮、图像等可交互控件中选中&#xff0c;如…

R语言单因素方差分析+差异显著字母法标注+逐行详细解释

R语言单因素方差分析 代码如下 df <- read.csv("data.csv",header TRUE,row.names 1) library(reshape2) df <- melt(df,idc()) names(df) <- c(trt, val) df aov1 <- aov(val~trt,datadf) summary(aov1)library(agricolae) data <- LSD.test(aov…

5 存储器映射和寄存器

文章目录 5.3 芯片内核5.3.1 ICache5.3.2 DCache5.3.3 FlexRAM 5.4 存储器映射5.4.1 存储器功能划分5.4.1.1 存储器 Block0 内部区域功能划分5.4.1.2 储存器 Block1 内部区域功能划分5.4.1.3 储存器 Block2 内部区域功能划分 5.5 寄存器映射5.5.1 GPIO1的输出数据寄存器 5.3 芯…

客户案例:EDLP助力金融行业打造高效数据防泄露体系

客户背景 某金融机构是一家以金融科技为核心&#xff0c;致力于为客户提供全方位、智能化、便捷化金融服务的综合性企业。公司总部位于南京&#xff0c;业务范围覆盖全国&#xff0c;拥有强大的技术研发团队和优秀的业务精英&#xff0c;为客户提供全方位的金融服务解决方案。 …

子类出现和父类同名的成员,子类如何访问父类的同名成员?

一. 子类访问子类同名的成员&#xff0c;直接访问即可。 #include <iostream> using namespace std;class Base { public:Base(int age 0) : m_age(age) {}int get_age() {return m_age;}static int get_counter() {return ms_counter;}int m_age;static int ms_counte…

融资经理简历模板

这份简历内容&#xff0c;以综合柜员招聘需求为背景&#xff0c;我们制作了1份全面、专业且具有参考价值的简历案例&#xff0c;大家可以灵活借鉴。 融资经理简历在线编辑下载&#xff1a;百度幻主简历 求职意向 求职类型&#xff1a;全职 意向岗位&#xff1a;融资经理 …

什么是网络攻击?阿里云服务器可以避免被攻击吗?

网络攻击是指:损害网络系统安全属性的任何类型的进攻动作。进攻行为导致网络系统的机密性、完整性、可控性、真实性、抗抵赖性等受到不同程度的破坏。 网络攻击有很多种&#xff0c;网络上常见的攻击有DDOS攻击、CC攻击、SYN攻击、ARP攻击以及木马、病毒等等&#xff0c;所以再…

xxl-job适配postgresql数据库

xxl-job支持了mysql数据库&#xff0c;其他的数据库适配得自己弄一下&#xff0c;下面以目前最新的2.4.1为例进行说明适配postgresql数据库的过程。 获取源代码 从github或gitee获取源代码&#xff0c;目前最新版本2.4.1 xxl官网&#xff1a;分布式任务调度平台XXL-JOB 建立…

Linux安装Java环境

处理安装环境 检查系统版本 [rootjeven ~]# cat /etc/centos-release CentOS Linux release 7.6.1810 (Core)检查系统内核版本 [rootjeven ~]# uname -r 6.1.8-1.el7.elrepo.x86_64清空卸载java环境&#xff08;如果已经安装了&#xff09; 查询java所在位置 [rootjeven …

什么是Anaconda?作用是?使用python必须要安装嘛?

一、什么是Anaconda以及其作用&#xff1f; 通俗来讲&#xff0c;Anaconda算是一个环境容器&#xff0c;也可以叫环境管理器。 作用&#xff1a;可以在Anaconda容器中为python项目创建不同的环境。在各个不同环境中可以安装不同版本的包并且各个环境互不影响。可以在使用不同项…

自动驾驶DCLC 功能规范

目录 1 概述Summary....................................................................................................... 4 1.1 目的Purpose....................................................................................................... 4 1.2 范围Ran…

每天学习一点点之 MySQL TINYINT

我已经不是第一次遇到关于 TINYINT 的问题了。在 MySQL 中&#xff0c;当我们将某个字段设置为 TINYINT&#xff0c;随着业务的扩展&#xff0c;我们可能会发现 TINYINT 的范围无法满足需求。这时需要修改字段属性。但如果表的数据量很大&#xff0c;或者由于分表导致涉及的表数…

java+springboot物流管理系统设计与实现wl-ssmj+jsp

物流管理系统的开发和综合性的物流信息网站平台的建设。研究的重点是运输管理信息系统&#xff0e;本系统是一套基于运输作业流程的管理系统&#xff0c;该系统以运输任务、货品、商务三大线索设计开发。运输任务是该管理系统的核心&#xff0c;系统通过对运输任务中的接收、调…

[cocos creator]EditBox,editing-return事件,清空输入框

需求&#xff1a; 监听EditBox&#xff0c;editing-return 回车事件&#xff0c;在输入框内点击回车后&#xff0c;发送内容&#xff0c;并清空输入框 问题&#xff1a; 设置node.getComponent(EditBox).string ; 没有效果 解决办法&#xff1a; //设置string 为空 this.v…

应用程序APP制作用Vue3CreateApp打包有什么优势?有哪些好处?

在当代的前端开发领域&#xff0c;Vue.js作为一个领先的JavaScript框架&#xff0c;一直处于技术革新和发展的前沿。Vue3作为该框架的最新版本&#xff0c;带来了更多的新特性和优化。在这些新特性中&#xff0c;createApp方法是一个非常值得关注的变化。对于开发者而言&#x…

MyBatis教程之逆向工程(十一)

正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库表。Hibernate是支持正向工程 的。逆向工程&#xff1a;先创建数据库表&#xff0c;由框架负责根据数据库表&#xff0c;反向生成如下资源&#xff1a; 1.Java实体类 2.Mapper…

使用easyExcel框架报错:服务器缺少字体

后台服务使用easyExcel框架生成表格&#xff0c;但是生成的时候报如下的错误&#xff1a; 这种报错其实就是部署服务的服务器缺少字体&#xff0c;正确的方法是安装字体。需要注意的是&#xff0c;测试环境服务器与生产环境服务器的在配置版本上可能存在差异&#xff0c;因此需…

初识Java 18-6 泛型

目录 潜在类型机制 支持潜在类型机制的语言 Python的潜在类型机制 C的潜在类型机制 Java中的直接潜在类型机制 潜在类型机制的替代方案 反射 将方法应用于序列中的每个元素 Java 8的潜在类型机制&#xff08;间接实现&#xff09; 潜在类型机制的使用例&#xff08;S…