MyBatis(二)

文章目录

  • 一.MyBatis的模式开发
    • 1.1 定义数据表和实体类
    • 1.2 配置数据源和MyBatis
    • 1.3 编写Mapper接口和增加xxxMapper.xml
    • 1.4 测试我们功能的是否实现.
  • 二. Mybatis的增删查改操作
  • 2.1 单表查询
  • 2.2 多表查询
  • 三.动态SQL的实现
    • 3.1 什么是动态SQL
    • 3.2 动态SQL的使用
      • if标签的使用
      • trim标签的使用
      • where标签的使用
      • set标签的使用
      • foreach标签的使用
    • 3.3 综合练习

一.MyBatis的模式开发

我们在开始MyBatis模式开发之前,我们首先来了解一下mybaits在整个框架的定位.看下图可知
在这里插入图片描述
MyBatis 也是一个ORM框架,ORM(Object Relational Mapping) ,即对象关系映射。在面向对象编程语言中,将关系型数据库中的数据与对象建立起映射关系,进而自动的完成数据与对象的互相转换:
1.将输入数据(即传入对象)+SQL映射成原生SQL
2.将结果集映射为返回对象,即输出对象

也就是说使⽤ MyBatis 可以像操作对象⼀样来操作数据库中的表,可以实现对象和数据库表之间
的转换,接下来我们来看 MyBatis 的使⽤吧.

使用过程中,还需要按照后端工程师的思路,来实现查询所有用户的功能.
在这里插入图片描述

1.1 定义数据表和实体类

创建数据表

 CREATE TABLE `userinfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) NOT NULL,
  `password` varchar(32) NOT NULL,
  `photo` varchar(500) DEFAULT '',
  `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `state` int(11) DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4

创建实体类

@Data
public class UserEntity {
    private Integer id;
    private String username;
    private String pwd;
    private String photo;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

1.2 配置数据源和MyBatis

在application.properties中配置以下内容

# mysql的配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
driver.class.driver-class-name=com.mysql.jdbc.Driver

#配置 MyBatis 中的 XML 路径
# 1.保存路径 2.xml格式
mybatis.mapper-locations=classpath:mybatis/**Mapper.xml

1.3 编写Mapper接口和增加xxxMapper.xml

我们现来实现查询所有用户的功能.

定义接口UserMapper接口:

@Mapper注解代表一个Mapper

@Mapper
public interface UserMapper {
 public List<UserEntity> getAll();}

定义UserMapper.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">\
<select id="getAll" resultType="com.example.demo.entity.UserEntity">
        select*from userinfo
    </select>
</mapper>

针对以上标签进行说明
标签:需要指定namespace 属性,表示命名空间,值为 mapper接口的全限定名,包括全包名.类名。
查询标签:是用来执行数据库的查询操作的:
id:是和Interface (接口)中定义的方法名称一样的,表示对接口的具体实现方法。
resultType:是返回的数据类型,也就是开头我们定义的实体类。

1.4 测试我们功能的是否实现.

我们会引入一个单元测试的概念,我们每实现一个功能没必要,都要去启动项目,然后去验证,这时候我们就可以启动单元测试.
在springboot中启动单元测试也是比较简单的事情,具体的步骤如下:

  1. 在要测试的类上石健Generate…
    在这里插入图片描述
    在这里插入图片描述

  2. 在测试方法中加上@SpringBootTest注解
    在这里插入图片描述
    直接执行此方法,得出查询结果.
    在这里插入图片描述

二. Mybatis的增删查改操作

我们在知道了基本的Mybatis的流程,我们来进行基本的增删改查操作

2.1 单表查询

UserMapper接口文件

 //根据id查询对象
    UserEntity getUserById(@Param("id") Integer id);
    //根据名称查询用户对象
    UserEntity getUseByUserName(@Param("username")String username);
    // 登录方法
    UserEntity login(UserEntity user);
    // 修改密码
    int updatePassword(@Param("id") Integer id,
                       @Param("password") String password,
                       @Param("newpassword") String newPassword);
    //删除操作
    int delById(@Param("id") Integer id);
    //增加用户
    int addUser(UserEntity user);
    //得到用户id
    int addUserGetID(UserEntity user);

    //根据用户模糊查询
    List<UserEntity> getListByName(@Param("username")String username);

Usermapper.xml文件

    <select id="getUserById" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo where id=#{id}
    </select>
    <select id="getUseByUserName" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo where username=${username}
    </select>
    <select id="login" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo where username= '${username}' and password= '${password}'
    </select>
    <update id="updatePassword">
        update userinfo set password=#{newpassword}
        where id = #{id} and password=#{password}
    </update>
    <delete id="delById">
        delete from userinfo where id=#{id}
    </delete>
    <insert id="addUser">
        insert into userinfo(username,password) values(#{username},#{password})
    </insert>
    <insert id="addUserGetID" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo(username,password) values(#{username},#{password})
    </insert>
    <select id="getListByName" resultMap="BaseMap">
        select id,username,password as pwd from userinfo where username like concat('%',#{username},'%')
    </select>

这上面有参数占位符,具体的解释如下;

#预编译处理。
$:字符直接替换。
预编译处理是指:MyBatis在处理f时,会将SQL 中的州替换为?号,使用PreparedStatement的set方法来赋值。
直接替换:是MyBatis 在处理$时,就是把$替换成变量的值。

这里来说明一下预编译处理和字符串直接替换

预编译处理(Prepared Statement)和字符串替换(String Replacement)是两种不同的数据库查询参数传递方式,它们在性能和安全性方面有着明显的区别。

预编译处理(Prepared Statement)

预编译处理是一种参数化查询的方式,在查询语句中使用占位符(通常是问号 “?”)来表示参数。
在执行预编译处理时,数据库会将SQL语句和参数分开处理,首先将SQL语句编译成一个准备好的查询模板,然后再将参数传递到模板中执行。
预编译处理将SQL语句与参数分开,因此能够有效地防止SQL注入攻击,提高了查询性能和安全性。
由于数据库在执行查询前已经对SQL语句进行了编译,所以对于多次执行相同查询但参数不同的情况,预编译处理能够提高性能,因为数据库可以重复使用相同的查询模板。
字符串替换(String Replacement):
字符串替换是一种直接将参数值嵌入到SQL语句中的方式。在查询语句中,直接将参数值拼接到SQL语句中的相应位置。
字符串替换的查询方式容易受到SQL注入攻击,因为恶意用户可以在参数值中插入恶意的SQL代码,破坏数据库或获取敏感数据。
由于字符串替换是每次执行查询都会生成一个新的SQL语句,所以对于相同查询的多次执行,每次都需要重新编译和执行,性能相对较低。

具体来说的话,我们来看下面的图示:
在这里插入图片描述

不知道大家注意到没有.上面的字符串替换,为什么会出现SQL注入问题,这里我用一张图给大家去解释
在这里插入图片描述

2.2 多表查询

在进行多表联查之前,我们还需要准备一个文章表

 CREATE TABLE `articleinfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL,
  `content` text NOT NULL,
  `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `uid` int(11) NOT NULL,
  `rcount` int(11) NOT NULL DEFAULT '1',
  `state` int(11) DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 |

插入了几条数据:
文章表的内容:

用户表的内容:
在这里插入图片描述
多表查询的接口类如下:

@Mapper
public interface ArticleMapper {
    //查询文章详情 一对一,一篇文章最多有一个作者
    ArticleInfoVO getDetail(@Param("id") Integer id);
    List<ArticleInfoVO> getArticleByUid(@Param("uid") Integer uid);

}

配置文件如下:

  <select id="getDetail" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select a.*,u.username from articleinfo a
        left join userinfo u on u.id=a.uid
        where a.id=#{id}
    </select>
    <select id="getArticleByUid" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select a.* ,u.username from articleinfo a
        left join userinfo u on u.id = a.uid
        where a.uid=#{uid}
    </select>

三.动态SQL的实现

3.1 什么是动态SQL

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

3.2 动态SQL的使用

if标签的使用

if标签用于在SQL语句中根据条件判断是否包含某个SQL片段。语法如下:

<select id="getUsers" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </where>
</select>

在上面的例子中,根据传入的name和age参数的值,如果它们不为空,就会拼接对应的SQL条件,实现动态的查询语句。

trim标签的使用

trim标签用于在SQL语句的头部或尾部去除多余的SQL片段,以避免不必要的SQL语法错误。trim标签还可以根据条件去除WHERE或AND等关键字,以确保动态SQL的正确性。
trim标签中有如下属性:
prefix:表示整个语句块,以prefix的值作为前缀
suffix:表示整个语句块,以suffix的值作为后缀.
prefixOverrides:表示整个语句块要去除掉的前缀.
suffixOverrides:表示整个语句块要去除掉的后缀

<select id="getUsers" resultType="User">
  SELECT * FROM users
  <trim prefix="WHERE" prefixOverrides="AND | OR">
    <if test="name != null">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
    <if test="gender != null">
      AND gender = #{gender}
    </if>
  </trim>
</select>

在上面的例子中,我们使用了trim标签来包裹if标签,prefix属性指定了在条件满足时在WHERE关键字之前添加"WHERE",prefixOverrides属性指定了当条件不满足时去除多余的"AND "或"OR "。

where标签的使用

where标签用于在SQL语句中包含WHERE子句,并根据条件动态拼接查询条件。

<select id="getUsers" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </where>
</select>

set标签的使用

根据传⼊的⽤户对象属性来更新⽤户数据,可以使⽤标签来指定动态内容。
UserMapper 接⼝中修改⽤户⽅法:根据传⼊的⽤户 id 属性,修改其他不为 null 的属性:

<update id="updateUser" parameterType="User">
  UPDATE users
  <set>
    <if test="name != null">
      name = #{name},
    </if>
    <if test="age != null">
      age = #{age},
    </if>
  </set>
  WHERE id = #{id}
</update>

foreach标签的使用

foreach的属性如下所示:
collection:绑定方法参数中的集合,如List,Set,Map或数组对象item:遍历时的每一个对象
open:语句块开头的字符串close:语句块结束的字符串
separator:每次遍历之间间隔的字符串
foreach标签用于在SQL语句中遍历集合,生成对应的SQL片段。它常用于批量插入或更新操作。

 <delete id="delByIdList">
        <!--        where id in(1,2..)-->
        delete from articleinfo
        where id in
        <foreach collection="idList" item="aid" open="(" close=")" separator=",">
            #{aid}
        </foreach>
    </delete>

这上面生成的语句,入下所示
delete from articleinfo where id in (1, 2, 3)

3.3 综合练习

在我们了解了基本的动态SQL标签之后,我们来一个综合的练习.
假设我们假如我们传入的参数都是非必须的.我们怎么才能完成SQL的拼接.
SQL如下:
select * from articleinfo WHERE id=? and title like concat(‘%’,?,‘%’)
我们传入参数的情况如下:
1.传入id,不传入title
2.传入title,不传入id
3.两个都不传
动态SQL的拼接策略如下:

方案一:

 <select id="getListByIdOrTitle" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select * from articleinfo
        where 1=1 
        <trim prefixOVerrides="and">
            <if test="id!=null and id>0">
               and id=#{id}
            </if>
            <if test="title!=null and title!=''">
                and title like concat('%',#{title},'%')
            </if>
        </trim>
    </select>

trim prefixOVerrides=“and”: 这是MyBatis的动态SQL标签trim的使用。trim标签用于在SQL语句的头部或尾部去除多余的SQL片段,并可以根据条件去除特定的关键字,如这里的and。prefixOverrides属性指定了当条件不满足时去除的前缀关键字,这里是and,表示如果条件不满足,就去除SQL语句中多余的and关键字。

方案二:

 <select id="getListByIdOrTitle" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select * from articleinfo
       <trim prefix ="where" suffixOverrides="and">
            <if test="id!=null and id>0">
                id=#{id}
            </if>
            <if test="title!=null and title!=''">
                and title like concat('%',#{title},'%')
            </if>
        </trim>
    </select>

中间解释:
trim prefix=“where” suffixOverrides=“and”>: 这是MyBatis的动态SQL标签trim的使用。trim标签用于在SQL语句的头部或尾部去除多余的SQL片段,并可以根据条件去除特定的关键字,如这里的and。prefix属性指定了在条件满足时在WHERE关键字之前添加"where",suffixOverrides属性指定了当条件不满足时去除SQL语句中多余的"and"。
方案三:

 <select id="getListByIdOrTitle" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select * from articleinfo
        <where>
            <if test="id!=null and id>0">
                id=#{id}
            </if>
            <if test="title!=null and title!=''">
                and title like concat('%',#{title},'%')
            </if>
        </where>
    </select>

where标签: 这是MyBatis的动态SQL标签的使用。where标签的作用是将包含在其中的条件片段包裹在WHERE子句中,如果条件满足,WHERE关键字和多余的AND或OR将会被自动添加,如果条件不满足,则WHERE关键字也不会出现在最终的查询语句中

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

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

相关文章

LeetCode559. N 叉树的最大深度

559. N 叉树的最大深度 文章目录 [559. N 叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-n-ary-tree/)一、题目二、题解方法一&#xff1a;迭代方法二&#xff1a;递归 一、题目 给定一个 N 叉树&#xff0c;找到其最大深度。 最大深度是指从根节点到最远叶…

【机器学习】Multiple Variable Linear Regression

Multiple Variable Linear Regression 1、问题描述1.1 包含样例的X矩阵1.2 参数向量 w, b 2、多变量的模型预测2.1 逐元素进行预测2.2 向量点积进行预测 3、多变量线性回归模型计算损失4、多变量线性回归模型梯度下降4.1 计算梯度4.2梯度下降 首先&#xff0c;导入所需的库 im…

架构的分类

目录 一、 RUP41 架构 1.1 RUP41架构方法概述 1.2 RUP41架构总体 1.3 RUP41架构方法内容 1.3.1 逻辑视图 1.3.2 开发视图 1.3.3 物理视图 1.3.4 处理视图 1.3.5 场景视图 ​二、 TOGAF9 架构 2.1 TOGAF9 架构概述 2.2 TOGAF9 架构分类 2.2.1 业务架构 2.2.2 数据架…

蓝海卓越计费管理系统远程命令执行

活着&#xff0c;就要时刻准备承受磨难&#xff01; 漏洞描述 蓝海卓越计费管理系统存在命令调试页面&#xff0c;导致攻击者可以远程命令执行 漏洞复现 访问 debug.php页面 远程调试命令执行 /debug.php漏洞证明 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝…

linux -网络编程-多线程并发服务器

目录 1.三次握手和四次挥手 2 滑动窗口 3 函数封装思想 4 高并发服务器 学习目标&#xff1a; 掌握三次握手建立连接过程掌握四次握手关闭连接的过程掌握滑动窗口的概念掌握错误处理函数封装实现多进程并发服务器实现多线程并发服务器 1.三次握手和四次挥手 思考: 为什么…

手把手教你使用stable diffusion生成自己的艺术二维码

艺术二维码制作指南 导读midjourneystable diffusion 环境准备安装stable diffusion webuisd-webui-qrcode-toolkit安装 草料二维码模型准备QR PatternQR Code MonsterIoC Lab Control Net 艺术二维码制作1. 二维码信息提取2. 使用QR Tookit生成二维码3. 下载二维码图片4. prom…

Modbus tcp转ETHERCAT网关modbus tcp/ip协议

捷米JM-ECT-TCP网关能够连接到Modbus tcp总线和ETHERCAT总线中&#xff0c;实现两种不同协议设备之间的通讯。这个网关能够大大提高工业生产的效率和生产效益&#xff0c;让生产变得更加智能化。捷米JM-ECT-TCP 是自主研发的一款 ETHERCAT 从站功能的通讯网关。该产品主要功能是…

一个监控系统的典型架构

监控系统的典型架构图&#xff0c;从左往右看&#xff0c;采集器是负责采集监控数据的&#xff0c;采集到数据之后传输给服务端&#xff0c;通常是直接写入时序库。然后就是对时序库的数据进行分析和可视化&#xff0c;分析部分最典型的就是告警规则判断&#xff0c;即图上的告…

【mysql学习篇】Order by与Group by优化以及排序算法详解

一、Order by与Group by优化 Case1&#xff1a; 分析&#xff1a; 利用最左前缀法则&#xff1a;中间字段不能断&#xff0c;因此查询用到了name索引&#xff0c;从key_len74也能看出&#xff0c;age索引列用在排序过程中&#xff0c;因为Extra字段里没有using filesort 注意…

擎创技术流 | 深入浅出运维可观测工具(二):eBPF应用中常见问题

上期跟大家聊了下eBPF的发展历史还有特性&#xff0c;点击这里↓↓↓擎创技术流 | 深入浅出运维可观测工具&#xff08;一&#xff09;&#xff1a;聊聊eBPF的前世今生&#xff0c;一键回看上期精彩内容。 这期主要跟大家分享下eBPF在应用过程中可能出现的问题&#xff0c;希望…

本地仓库推送至远程仓库

1. 本地生成ssh密钥对 ssh-keygen -t rsa -C 邮箱2. 添加公钥到gitlab/github/gitee上 打开C:\Users\用户名\.ssh目录下生成的密钥文件id_rsa.pub&#xff0c;把内容复制到如下文本框中 删除Expiration date显示的日期&#xff0c;公钥有效期变成永久&#xff0c;之后点Add K…

vmware中windows操作系统虚拟机安装

1.win10中安装 1.1 虚拟机向导 文件-新建虚拟机 典型-下一步 稍后安装操作系统-下一步 window10 64x -下一步 修改虚拟机名称及位置-下一步 默认60g,至少大于40g-将虚拟磁盘拆分成多个文件夹-下一步 点击完成 1.2 编辑虚拟机设置 移除打印机 设置虚拟机&#xff0c;加入iso映…

联想北京公司研发管理部高级经理周燕龙受邀为第十二届中国PMO大会演讲嘉宾

联想&#xff08;北京&#xff09;有限公司研发管理部高级经理周燕龙先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;PMO如何助力研发。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; PMO在…

js中的遍历方法比较:map、for...in、for...of、reduce和forEach的特点与适用场景

&#x1f60a;博主&#xff1a;小猫娃来啦 &#x1f60a;文章核心&#xff1a;JavaScript中的遍历方法比较&#xff1a;map、for…in、for…of和forEach的特点与适用场景 文章目录 map 方法概述用法返回值特点 for...in 循环概述用法注意事项 for...of 循环概述用法可迭代对象…

用LangChain开源框架实现知识机器人

前言 Large Language Models (LLMs)在2020年OpenAI 的 GPT-3 的发布而进入世界舞台 。从那时起&#xff0c;他们稳步增长进入公众视野。 众所周知 OpenAI 的 API 无法联网&#xff0c;所以大家如果想通过它的API实现联网搜索并给出回答、总结 PDF 文档、基于某个 Youtube 视频…

[nlp] TF-IDF算法介绍

&#xff08;1&#xff09;TF是词频(Term Frequency) 词频是文档中词出现的概率。 &#xff08;2&#xff09; IDF是逆向文件频率(Inverse Document Frequency) 词条出现率越低&#xff0c;IDF越大。

Dooring-Saas低代码技术详解

hello, 大家好, 我是徐小夕, 今天和大家分享一下基于 H5-Dooring零代码 开发的全新零代码搭建平台 Dooring-Saas 的技术架构和设计实现思路. 背景介绍 3年前我上线了第一版自研零代码引擎 H5-Dooring, 至今已迭代了 300 多个版本, 主要目的是快速且批量化的生产业务/营销过程中…

红黑树解密:为什么根节点必须是黑色,两个红色节点不能挨着?

红黑树解密&#xff1a;为什么根节点必须是黑色&#xff0c;两个红色节点不能挨着&#xff1f; 博主简介一、引言1.1、红黑树是什么及其特点1.2、根节点为黑色和红色节点不连续的性质介绍 二、为何根节点必须是黑色&#xff1f;三、为何两个红色节点不能挨着&#xff1f;总结 博…

RNN架构解析——LSTM模型

目录 LSTMLSTM内部结构图 Bi-LSTM实现 优点和缺点 LSTM LSTM内部结构图 Bi-LSTM 实现 优点和缺点

Windows系统如何修改文件日期属性

winr键&#xff0c;输入powershell,在弹出的命令窗口输入命令&#xff0c;案例如下&#xff1a; file_address E:\_OrderingProject\\PIC1101\ldv1s_0830_ec_result.tiftime_change "07/12/2022 20:42:23" 修改文件创建时间&#xff1a;creationtime $(Get-Item fi…