MyBatis操作数据库表和动态SQL的使用

目录

1.MyBatis开发环境的搭建和测试

2.MyBatis基本操作

2.0 准备工作

2.1 新增操作

2.2 删除、修改、查询操作

2.3 #{param} 和 ${param}的使用和区别

2.4 实体对象属性和数据库字段名称不同时如何映射?

3. MyBatis多表查询

3.0 准备工作

3.1 一对一的表的映射

3.2 一对多的表的映射

4.MyBatis动态SQL

4.0 准备工作

4.1 if-标签

4.2 trim-标签

4.3 where-标签

4.4 set-标签

4.5 foreach-标签


1.MyBatis开发环境的搭建和测试

MyBatis环境的搭建和测试可以参考之前发布的:MyBatis基本介绍以及开发环境的搭建和测试

2.MyBatis基本操作

我们先来使用MyBatis实现基本表的增删改查操作,在熟悉了这些基本操作后,再来学习MyBatis多表查询的实现。在进行学习之前,我们还是来回顾下MyBatis在我们后端程序中的地位:


我们在上一篇文章中学习到,MyBatis是通过定义mapper接口并找到对应的实现接口的xml文件整合,最后动态生成sql,借助jdbc操作来操作数据库的。所以我们对数据库表的操作从整体上应当分为两步:

  1. 定义mapper接口
  2. 定义实现mapper接口的MyBatis的XML文件

接下来我们通过学习MyBatis的基本操作来理解上述它操作数据库的两个步骤。下面我们的操作都基于下面这个项目的框架模板进行:

2.0 准备工作

 下面我们将要学习的的四种基本操作基于之前搭建环境时在数据库创建的一张user表来实现。在开始之前我们要先创建好用户相关的mapper接口和和数据库中user表对应的实体映射类,如下图:

2.1 新增操作

MyBatis实现基本新增操作的整体步骤:

  1. 在UserMapper接口中声明新增用户的方法
  2. 在对应的实现接口的xml文件中编写<insert>标签实现接口方法

实现过程中的注意事项和实现细节如下图:

2.2 删除、修改、查询操作

这些操作与2.1中的实现步骤类似,我们将其总结到了一块:

  1. 在UserMapper接口中定义相关的服务方法
  2. 在UserMapper.xml文件中选用对应的标签并编写sql语句实现接口中的方法

其中,各个操作的详细步骤和注意事项如下:

2.3 #{param} 和 ${param}的使用和区别

在上面的UserMapper的xml文件中,我们提到对于sql语句中未知量的赋值可以通过#{param}或者${param}赋值。那么既然都可以用来给sql语句赋值,那么它们之间有什么使用上的区别呢?(param:可能是传递的对象中的属性值也可能是传递的参数值)


1. '$'是直接替换,'#'是预处理。

这样说可能我们都不太好理解,我们来实际应用中看一下:

2.使用‘$’可能会存在sql注入的问题,使用'#'是安全的。

既然‘$’是直接替换,那么sql注入的安全问题就来了,下面我们来看一下使用$时带来的sql注入安全问题:


 那既然$和#都能实现需求,为什么不直接全是用#而还要有$呢?

这是因为在需要传递的参数是数据库中的关键字时,比如需要升序或降序排序的场景下我们必须使用$来拼接as或者desc字段,只能使用$,使用#就无法实现这个功能了。

比如:

-- 正常情况下,使用$传递排序参数(asc、desc)数按照id字段升序排列用户的sql语句
select * from user order by id asc;

-- 而使用 # 传递排序参数的sql语句形态为:(错误sql❌)
select *from user order by id 'asc';

2.4 实体对象属性和数据库字段名称不同时如何映射?

不知道大家有没有发现,我们在上面User实体类中有些属性的命名是不规范的,这是为了符合数据库的规范以求能够映射数据到相应实体对象的字段上。

同时在实际的开发中,由于开发人员和数据库设计人员可能不是同一个人来完成的,同时数据库规范和Java开发规范优势不相同的。那么就非常可能存在数据库表的字段名和开发中实体类的属性名不相同。那么在默认查询时使用我们的select标签的resultType指定的实体对象中的属性名由于和数据库中对应表的字段名不同,就不能正常映射数据库表中字段的值了。那么应该如何解决这种映射问题呢?我总结了以下两种方法:


1. 写查询语句时将查询字段重命名为我们实体对象中对应的属性名,即可正确映射。


 

2.使用resultMap属性,设计表字段和实体类属性的映射关系。

3. MyBatis多表查询

3.0 准备工作

为了学习MyBatis多表查询,我们在数据库中再创建一张评论表,这个评论表中有一个用户编号属性来指明该条评论是那个用户发表的,如下:


 对数据库中的评论表,在程序中创建Comment实体以及CommentMapper接口和实现的xml文件:

3.1 一对一的表的映射

这里我们通过查询评论表来学习一对一的表的映射。在我们返回给前端评论表中指定评论的信息时,需要返回的是评论的用户而不是评论表中的用户的id信息。评论表中的用户和用户表中的用户是一对一的关系,要实现返回给前端的数据中包含评论的相关信息以及评论的用户的名称而不是评论用户id,这个时候我们应该怎么做呢?


定义一个Comment视图实体对象,其中包含用户名属性。在进行数据库查询时使用联表查询,返回给前端这个视图实体对象中的信息即可!

如下图所示:

3.2 一对多的表的映射

如果现在我们要根据用户编号查询其发布的所有评论?又该如何实现呢?其实虽然用户和评论之间存在一对多的关系,但是仔细一看就会发现,我们的评论表中就存在着用户编号,所以我们通过单表查询就可以完成这个需求:

  

4.MyBatis动态SQL

4.0 准备工作

为了学习MyBatis动态SQL中使用的标签,我们接着上面的学习,再在MySQL的user用户表中新增一个默认约束的头像字段。下面我们的学习将使用到这个字段。

4.1 if-标签

在MyBatis中,if标签常用来判断:当某一条件满足时才进行SQL语句的拼装,这个判断条件写在MyBatis的xml文件中的if标签的test属性中。

<insert id="addDefault"  useGeneratedKeys="true" keyProperty="id">
    insert into user(
    username,
    password
    <if test="photo != null">
        ,photo
    </if>)
    values (
    #{username},
    #{password}
    <if test="photo != null">
        , #{photo}
    </if>)
</insert>

比如现在的需求,用户在注册时可以不上传头像,此时默认使用数据库中默认约束所指定的头像信息。那么我们应该如何编写SQL语句呢?if标签使用的注意事项和细节又有哪些呢?让我们通过实现上面的需求来一起探索:

4.2 trim-标签

在4.1的需求中,只有photo是一个选填项。如果现在有一个需求:所有用于填写的字段都是选填项,在数据库中也有对应的默认值约束。这个时候又应该怎么实现呢?

很显然,此时就不能再继续使用if标签了,这是因为:


于是这个时候就需要我们的trim标签登场了!我们先来看下trim标签有哪些关键字:

  1. prefix——前缀值
  2. suffix——后缀值
  3. prefixOverrides——整个语句块要去掉的前缀
  4. suffixOverrides——整个语句块要去掉的后缀
<insert id="addAllDefault" 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="photo != null">
            photo,
        </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
        <if test="username != null">
            #{username},
        </if>
        <if test="password != null">
            #{password},
        </if>
        <if test="photo != null">
            #{photo},
        </if>
    </trim>
</insert>

我们使用trim标签来实现上述当所有字段非必填时的用户注册的需求,同时总结一下trim标签的使用注意事项及细节:

4.3 where-标签

听名知意😄,where想必就是给我们SQL语句中where判读条件使用的。使用where标签时,有以下几个细节:

  1. 使用where标签时,我们不用再手写sql语句中的where关键字。
  2. 当where标签中没有任何条件时,where关键字会被省略
  3. where标签会帮助我们删除SQL中的前缀 ‘and’关键字
  4. 通trim标签一致,where标签通常也和if标签搭配使用
<select id="getUserByNameOrPwd" resultType="com.example.demo.entity.User">
    select id,username,password,createtime 'createTime',photo
    from user
    <where>
        <if test="username != null">
            and username=#{username}
        </if>
        <if test="password != null">
            and password=#{password}
        </if>
    </where>
</select>

上面这种学习where标签的方式还不太直观,假设现在我们要实现管理员根据用户名或者密码查询指定user表中符合条件的用户的操作,下面我们使用MyBatis提供的where标签实现动态查询SQL实现上述需求:

4.4 set-标签

用来动态设置我们再MyBatis的xml文件中编写的sql语句中的set字段后的值,set标签的使用细节及注意事项如下:

  1. set标签中没有我们必须要去指定的关键字
  2. set标签会帮助我们删除sql语句中的后缀英文逗号
<update id="updateUserInfo">
    update user
    <set>
        <if test="username != null">
            username=#{username},
        </if>
        <if test="password">
            password=#{password},
        </if>
        <if test="photo">
            photo=#{photo},
        </if>
    </set>
    where id=#{id}
</update>

了解了set标签的作用,我们就想到了它可以用于信息的修改的需求,当我们不知道用户究竟要修改某个表中的那个字段时,可以通过set标签结合前端传递的参数来动态的组合sql语句中set语句块的值,实现动态信息的修改。老规矩,我们还是实现下上述需求来总结下set标签使用的规则和注意事项:

4.5 foreach-标签

当我们在遇到需要批量操作数据的场景时,MyBatis提供的foreach标签是我们的不二选择。可能有的同学和我当初想的一样,直接在服务层加一层循环挨个处理持久层前端传过来得数据集合不就可以吗?是可以,但是效率就要低很多了!接下来我们将使用foreach标签啦进行批量请求处理。我们先来看下foreach标签中需要我们手动指定得一些关键字:

  1. collection——方法中集合参数名
  2. item——进行遍历的每一个对象名
  3. open——语句块开头的字符串
  4. close——语句块结束的字符串
  5. separator——每次遍历间隔之间的字符串

例:

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

下面还是老规矩,我们借助foreach来实现批量删除用户的操作总结以下foreach标签的使用及其注意事项:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ELK企业级日志分析系统

ELK概述 为什么要使用 ELK 日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷&#xff0c;性能安全性&#xff0c;从而及时采取措施纠正错误。 往…

切比雪夫不等式,大数定律及极限定理。

一.切比雪夫不等式 1.定理 若随机变量X的期望EX和方差DX存在,则对任意ε > 0,有   P{ |X - EX| > ε } < DX/ε2 或 P{ |X - EX| < ε } > 1 - DX/ε2 2.解析定理 ①该定理对 X 服从什么分布不做要求&#xff0c;仅EX DX存在即可。 ②“| |” 由于X某次…

软件测试炸了,作为从业者,你做好准备了吗?

软件测试行业已经发生很大变化&#xff0c;你跟上变化了吗&#xff1f; 岗位少不可怕&#xff0c;要求越来越高也不可怕&#xff0c;可怕的是&#xff0c;软件测试行业已经发生巨变&#xff0c;而你却原地踏步&#xff01;目前一线大厂更多倾向于招收测试开发&#xff0c;或者…

自学网络安全(黑客),一般人我劝你还是算了吧

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习 我在之前的回答中&#xff0c;我都一再强调不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而且…

torch.distributed.launch多卡多机

torch.distributed.launch命令介绍 我们在训练分布式时候&#xff0c;会使用到 torch.distributed.launch 可以通过命令&#xff0c;来打印该模块提供的可选参数 python -m torch.distributed.launch --help usage: launch.py [-h] [--nnodes NNODES] [--node_rank NODE_RANK]…

诚迈科技携智达诚远出席高通汽车技术与合作峰会

5月25日至26日&#xff0c;诚迈科技及旗下的智能汽车操作系统及中间件产品提供商智达诚远作为高通生态伙伴&#xff0c;亮相首届“高通汽车技术与合作峰会”&#xff0c;通过产品展示和主题演讲呈现了基于高通骁龙数字底盘的最新智能座舱技术成果&#xff0c;共同展望智能网联汽…

GcExcel v6.1 支持新的 ‘.sjs‘ 模板文件 ‘.xltx‘ 格式 Crack

GrapeCity Documents for Excel (GcExcel) v6.1 版本现已上线&#xff01;该版本支持新的 SpreadJS .sjs 文件格式和 Excel 模板文件 .xltx 格式。此外&#xff0c;GcExcel 支持更多的SpreadJS兼容性功能和对 GcDataViewer 的多项增强。看看下面的主要亮点。 导入/导出 Spread…

Revit幕墙:用幕墙巧做屋面瓦及如何快速幕墙?

一、Revit中用幕墙巧做屋面瓦 屋面瓦重复性很高&#xff0c;我们如何快速的创建呢?下面我们来学会快速用幕墙来创建屋面瓦的技巧。 1.新建“公制轮廓-竖挺”族&#xff0c;以此来创建瓦的族(以便于载入项目中使用) 2.在轮廓族中绘制瓦的轮廓(轮廓需要闭合)&#xff0c;将族名称…

【JavaSE】Java基础语法(三十四):实现多线程

文章目录 1. 简单了解多线程2. 并发和并行3. 进程和线程4. 实现多线程方式一&#xff1a;继承Thread类【应用】5. 实现多线程方式二&#xff1a;实现Runnable接口【应用】6. 实现多线程方式三: 实现Callable接口【应用】7. 设置和获取线程名称【应用】8. 线程休眠【应用】9. 线…

Z-Library2023现状

网上基本上年年都会传出来Z-Library要被干掉的消息&#xff0c;我一直觉得&#xff0c;如果那真的发生了&#xff0c;会是人类的悲哀。 由于之前我存储的地址又挂了&#xff0c;所以紧急又寻找了一下。 1.朋友帮忙 朋友帮我搜了一下&#xff0c;发现有三个地址。 他说这第一个…

xlsx是什么格式

xlsx是什么格式? xlsx是Excel文档的扩展名&#xff0c;其基于Office Open XML标准的压缩文件格式&#xff0c;取代了其以前专有的默认文件格式&#xff0c;在传统的文件名扩展名后面添加了字母x&#xff0c;即.xlsx取代.xls。 xlsx文件是什么格式? xlsx是Excel表格的文件格…

【P34】JMeter ForEach控制器(ForEach Controller)

文章目录 一、ForEach控制器&#xff08;ForEach Controller&#xff09;参数说明二、准备工作三、测试计划设计 一、ForEach控制器&#xff08;ForEach Controller&#xff09;参数说明 可以对一个组变量进行循环迭代&#xff1b;该组件通常与后置处理器中的 JSON 提取器、正…

桥梁结构健康监测解决方案

城市桥梁担负着城市的交通和运输网络的重要角色&#xff0c;是城市生命线的重要组成部分。然而&#xff0c;随着时间的推移和日益增长的负荷&#xff0c;桥梁可能会受到各种因素的损害&#xff0c;如自然灾害、疲劳、腐蚀等。因此&#xff0c;桥梁结构健康监测变得至关重要&…

chatgpt赋能Python-python中怎么导入numpy

介绍 Python是一种广泛使用的编程语言&#xff0c;具有许多内建功能和模块&#xff0c;让开发者能够快速地编写代码。然而&#xff0c;虽然能够实现许多计算&#xff0c;但是原始Python本身并不足够处理各种科学和数字计算上需要的高效性&#xff0c;因此numpy这个开源的Pytho…

【机器学习】采样方法

文章目录 采样方法11.1 简介11.2 常见采样方法11.2.1 均匀分布采样11.2.2 逆变换采样11.2.3 拒绝采样11.2.4 重要采样11.2.5 Metropolis方法11.2.6 Metropolis-Hasting 算法11.2.7 吉布斯采样 采样方法 11.1 简介 什么是采样 从一个分布中生成一批服从该分布的样本&#xff0c…

JavaWeb ( 十 ) SpringMVC

4.Spring MVC Spring MVC是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架。 三层架构分为表述层&#xff08;或表示层)、业务逻辑层、数据访问层&#xff0c;表述层表示前台页面和后台servlet 4.1.Spring MVC优点&#xff1a; ① 基于原生的Servlet&#xff0c;通过…

API测试| 了解API接口测试| API接口测试指南

什么是API&#xff1f; API是一个缩写&#xff0c;它代表了一个 pplication P AGC软件覆盖整个房间。API是用于构建软件应用程序的一组例程&#xff0c;协议和工具。API指定一个软件程序应如何与其他软件程序进行交互。 例行程序&#xff1a;执行特定任务的程序。例程也称为过…

MKS SERVO4257D 闭环步进电机_系列1 产品简介

第1部分 产品概述 1.1 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口&#xff0c;RS485接口和CAN接口&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&#xff0c;有…

【工具】vscode的常用插件之git插件

&#x1f41a;作者简介&#xff1a;花神庙码农&#xff08;专注于Linux、WLAN、TCP/IP、Python等技术方向&#xff09;&#x1f433;博客主页&#xff1a;花神庙码农 &#xff0c;地址&#xff1a;https://blog.csdn.net/qxhgd&#x1f310;系列专栏&#xff1a;善假于物&#…

进程间通信(命名管道)

目录&#xff1a; 1.命名管道 2.创建命名管道 --------------------------------------------------------------------------------------------------------------------------------- 1.命名管道 1.管道的一个应用限制就是只能在具有共同祖先&#xff08;具有亲缘关系&…
最新文章