MyBatis操作数据库

1.MyBatis是什么?

MyBatis 是⼀款优秀的持久层框架,它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了⼏乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和 Java POJO(Plain Old Java Objects,普通⽼式 Java 对象)为数据库中的记录。

简单来说 MyBatis 是更简单完成程序和数据库交互的⼯具,也就是更简单的操作和读取数据库⼯具。

2.为什么要学习MyBatis?

对于后端开发来说,程序是由以下两个重要的部分组成的:

  1. 后端程序
  2. 数据库

在这里插入图片描述
对于 JDBC 来说,整个操作⾮常的繁琐,我们不但要拼接每⼀个参数,⽽且还要按照模板代码的⽅式,⼀步步的操作数据库,并且在每次操作完,还要⼿动关闭连接等,⽽所有的这些操作步骤都需要在每个⽅法中重复书写。于是我们就想,那有没有⼀种⽅法,可以更简单、更⽅便的操作数据库呢?
答案是肯定的,这就是我们要学习 MyBatis 的真正原因,它可以帮助我们更⽅便、更快速的操作数据库。

3.学习MyBatis

MyBatis 学习分为两部分:

  • 配置 MyBatis 开发环境;
  • 使⽤ MyBatis 模式和语法操作数据库。

4.第一个MyBatis查询

开始搭建 MyBatis 之前,我们先来看⼀下 MyBatis 在整个框架中的定位,框架交互流程图:
在这里插入图片描述在MyBatis中,程序员需要做如下几件事;

  1. SQL语句 (可以写在java代码中,也可以写在MyBatis配置文件中)
  2. 传参(非必须)
  3. 结果映射(可以写在java代码中,也可以写在MyBatis配置文件中)

4.1 创建数据库和表

-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使⽤数据数据
use mycnblog;
-- 创建表[⽤户表]
drop table if exists userinfo;
create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default '',createtime datetime default now(),updatetime datetime default now(),`state` int default 1
) default charset 'utf8mb4';-- 添加⼀个⽤户信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`,`createtime`, `updatetime`, `state`) VALUES(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);

4.2 添加MyBatis框架⽀持

新项目添加MyBatis

在创建项目是添加MyBatis依赖:
在这里插入图片描述

老项目添加MyBatis

1.下载插件

在这里插入图片描述

2.右击generate

在这里插入图片描述

3.搜索”MyBatis“添加

在这里插入图片描述

4.3 配置连接字符串和MyBatis

配置连接字符串

在配置文件中添加如下内容,这里在application.yml文件中添加:

# 数据库连接配置
spring:datasource:url: jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=falseusername: rootpassword: 111111driver-class-name: com.mysql.cj.jdbc.Driver

配置 MyBatis 中的 XML 路径

# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:mapper-locations: classpath:mapper/**Mapper.xml

在配置文件中建一个mapper文件夹:
在这里插入图片描述

4.4 添加业务代码

按照如下流程来实现MyBatis查询所有用户的功能:
在这里插入图片描述

添加实体类

添加用户的实体类(属性需要和字段名一致):

@Data
public class User {private Integer id;private String username;private String password;private String photo;private Date createtime;private Date updatetime;
}

添加mapper接口

@Mapper
public interface userMapper {//查询public List<User> queryAll();
}

添加sql语句,实现接口
在配置文件的mapper文件夹中,定义UserMapper.xml 查询所有⽤户的具体实现 SQL:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
s.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mybatisdemo.mapper.UserMapper"><select id="queryAll" resultType="com.example.mybatisdemo.model.User">select * from userinfo</select>
</mapper>

以下是对以上标签的说明:

  • mapper标签:需要指定 namespace 属性,表示命名空间,值为 mapper 接⼝的全限定 名,包括全包名.类名。
  • select查询标签:是⽤来执⾏数据库的查询操作的:
  • id:是和 Interface(接⼝)中定义的⽅法名称⼀样的,表示对接⼝的具体实现⽅法。
  • resultType:是返回的数据类型,也就是开头我们定义的实体类

测试一下: 在接口页面右键选择generate,点击test:
在这里插入图片描述
选择要测试的方法:
在这里插入图片描述
会自动生成测试方法。

测试一下

UserMapperTest.java代码:

@Slf4j
@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid queryAll() {List<User> users = userMapper.queryAll();log.info(users.toString());}
}

如何传参

添加sql语句:根据id查询:通过 “#” 传参

    <select id="queryById" resultType="com.example.mybatisdemo.model.User">select * from userinfo where id=#{uid}</select>

添加mapper接口:

    //根据id查询User queryById(@Param("uid") Integer id);

@Param是重命名

补充: 当只有一个参数时,可以不加注解,并且参数名称可以不一样,如下图所示:

在这里插入图片描述

5.增删改操作

  • insert标签:插⼊语句
  • update标签:修改语句
  • delete标签:删除语句

5.1 增加数据

方法声明:

    //插入Integer insert(User user);

添加sql语句:

    <insert id="insert">insert into userinfo(username,password,photo) values(#{username},#{password},#{photo})</insert>

通过"#"传参:
在这里插入图片描述

如果设置了param注解,就必须要使用param注解的命名:

方法声明:

Integer insert1(@Param("userinfo") User user);

SQL语句:

    <insert id="insert1">insert into userinfo(username,password,photo) values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})</insert>

特殊的添加:返回自增的id

默认情况下返回的是受影响的⾏号,如果想要返回⾃增 id,具体实现如下:

方法声明:

Integer insert1(@Param("userinfo") User user);

UserMapper.xml:

    <insert id="insert1" useGeneratedKeys="true" keyProperty="id" >insert into userinfo(username,password,photo) values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})</insert>
  • useGeneratedKeys:这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动递增字段),默认值:false。
  • keyColumn:设置⽣成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第⼀列的时候,是必须设置的。如果⽣成列不⽌⼀个,可以⽤逗号分隔多个属性名称。
  • keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或 insert 语句的selectKey ⼦元素设置它的值,默认值:未设置(unset)。如果⽣成列不⽌⼀个,可以⽤逗号分隔多个属性名称。

5.2 修改数据

方法声明:

    //修改void update(User user);

UserMapper.xml:

    <update id="update">update userinfo set username=#{username},password=#{password} where id=#{id}</update>

5.3 删除数据

方法声明:

    //删除void delete(Integer id);

UserMapper.xml:

    <delete id="delete">delete from userinfo where id=#{id}</delete>

6.表单查询

6.1 参数占位符 #{} 和 ${}

  • #{}:预编译处理。
  • ${}:字符直接替换。

预编译处理是指:MyBatis 在处理#{}时,会将 SQL 中的 #{} 替换为?号,使⽤ PreparedStatement的 set ⽅法来赋值。

直接替换:是MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值。

举个例子来看看这两者的区别:

  1. ⼀般航空公司乘机都是头等舱和经济舱分离的,头等舱的⼈先登机,登机完之后,封闭经济舱,然后再让经济舱的乘客登机,这样的好处是可以避免浑⽔摸⻥,经济舱的⼈混到头等舱的情况,这就相当于预处理,可以解决程序中不安全(越权处理)的问题
  2. ⽽直接替换的情况相当于,头等舱和经济舱不分离的情况,这样经济舱的乘客在通过安检之后可能越权摸到头等舱,这就相当于参数直接替换,它的问题是可能会带来越权查询和操作数据等问题。比如6.3的sql注入问题。

6.2 使用 ${} 在排序查询中的优势

使用 #{} 进行排序查询

方法声明:

    //排序List<User>queryByOrder(String order);

使用 #{} 进行排序查询:

    <select id="queryByOrder" resultType="com.example.mybatisdemo.model.User">select * from userinfo order by #{order}</select>

查询测试:

    void queryByOrder() {List<User>users=userMapper.queryByOrder("desc");log.info(users.toString());}

运行结果如下所示:
在这里插入图片描述
这是因为当使⽤ #{sort} 查询时,如果传递的值为 String 则会加单引号,就会导致 sql 错误。

使用 ${} 进行排序查询

排序时,只能使用 $ 。

使用 ${} 进行排序查询则查询成功:

    <select id="queryByOrder" resultType="com.example.mybatisdemo.model.User">select * from userinfo order by id ${order}</select>

但是它有可能会引起sql注入问题。即用户输入的参数中,有可能带有恶意sql。

解决方法:可以在前端只能让用户进行点击,选择排序方式,参数由后端控制输入,后端在查询之前,对参数进行校验,只能传 desc 和 asc 两个值。

6.3 sql注入

SQL注入(SQL lnjection)是发生在Web程序中数据库层的安全漏洞,是比较常用的网络攻击方式之一,他不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至修改数据库。也就是说,SQL注入就是在用户输入的字符串中添加SQL语句,如果在设计不良的程序中忽略了检查,那么这些注入进去的SQL语句就会被数据库服务器误认为是正常的SQL语句而运行,攻击者就可以执行计划外的命令或者访问未授权的数据。

6.4 like 查询

like 查询是一个模糊查询。使⽤ #{} 会报错,而这个又不能直接使用 ${},会有sql注入问题,可以考虑使⽤ mysql 的内置函数 concat() 来处理,实现代码如下:

concat ()方法用于连接字符串

方法声明:

    List<User>queryByLike(String name);

UserMapper.xml:

    <select id="queryByLike" resultType="com.example.mybatisdemo.model.User">select * from userinfo where username like concat('%',#{name},'%')</select>

6.4 如何打印sql日志

在配置文件中添加如下文件即可:

# 配置打印 MyBatis 执行的 SQL
mybatis:configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

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

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

相关文章

【机器学习】吃瓜教程 | 西瓜书 + 南瓜书 (1)

文章目录 一、绪论1、什么是机器学习&#xff1f;2、基本术语3、假设空间4、归纳偏好5、发展历程 二、模型评估与选择A、一种训练集一种算法2.1 经验误差 与 过拟合2.2 评估方法a) 留出法b) 交叉验证法c) 自助法d) 调参与最终模型 2.3 性能度量a) 错误率与精度b) 查准率、查全率…

matlab dot()函数求矩阵内积,三维 ,多维 详解

matlab dot()函数求矩阵内积&#xff0c;三维 &#xff0c;多维 详解 Cdot(A,b,X)&#xff0c;这个参数X 只能取1,或者2。1 表示按列&#xff0c;2表示按行&#xff0c;如果没有参数。默认按列。 1&#xff09;按列优先计算 Cdot(A,B)dot(A,B,1)[a1*b1a4*b4 ,a2*b2a5*b5 ,a…

视频拼接得AI三维生成方案-开端(一)

想使用二维得图像生成三维得空间图像&#xff0c;英伟达有完整得方案&#xff0c;开源&#xff0c;但是三维拼接不一样&#xff0c;只需要二维&#xff0c;并且要实时&#xff0c;如何生成是我每天都在思考得东西。 cnn 提取特征器和自编码 在训练细胞神经网络时&#xff0c;问…

linux shell比较命令

1 比较运算 num1-eq num2 等于 [ 3 -eq $mynum ] num1-ne num2 不等于 [ 3 -ne $mynum ] num1-lt num2 小于 [ 3 -lt $mynum ] num1-le num2 小于或等于 [ 3 -le $mynum ] num1-gt num2 大于 [ 3 -gt $mynum ] num1-ge num2 大于或等于 [ 3 -ge $mynum ]。 filename1-nt filen…

linux上面修改u盘的名称

首先df-h显示文件系统磁盘空间使用情况 df -hFilesystem Size Used Avail Use% Mounted on /dev/sda1 39G 24G 13G 66% / tmpfs 990M 4.5M 986M 1% /dev/shm /dev/sda2 77G 62G 12G 85% /broncho /dev/s…

C++ PCL点云圆柱结构提取/立杆结构提取

目录 一、算法实现二、结果展示适用于圆柱体提取、立杆提取。 一、算法实现 #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #in

大数据分析案例-基于LightGBM算法构建乳腺癌分类预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

jmeter软件测试实验(附源码以及配置)

jmeter介绍 JMeter是一个开源的性能测试工具&#xff0c;由Apache软件基金会开发和维护。它主要用于对Web应用程序、Web服务、数据库和其他类型的服务进行性能测试。JMeter最初是为测试Web应用程序而设计的&#xff0c;但现在已经扩展到支持更广泛的应用场景。 JMeter 可对服务…

AcWing 244. 谜一样的牛—树状数组、二分

题目链接 AcWing 244. 谜一样的牛 题目描述 分析 这道题挺巧妙的&#xff0c;感觉树状数组方面的题就是比较难想&#xff0c;先分析一下样例&#xff0c;样例中每头牛前面比自己低的牛的数量分别为 0 1 2 1 0牛的高度是1~n的排列&#xff0c;如何分析出每头牛的高度呢&…

MySQL-多表查询-小结1

目录 内连接 外连接 子查询&#xff08;嵌套查询&#xff09; 内连接 内连接查询的是表之间交集的部分隐式内连接 select 字段列表 from 表1&#xff0c;表2 where 条件....&#xff1b;显示内连接 select 字段列表 from 表1 [inner] join 表2 on 条件....&#xff1b; 外连…

API Testing 一个基于 YAML 文件的开源接口测试工具

目录 前言&#xff1a; 如何使用&#xff1f; 本地模式 服务端模式 文件格式 后续计划 前言&#xff1a; API Testing 是一个基于 YAML 文件的开源接口测试工具&#xff0c;它可以帮助开发者快速地进行接口测试。 在选择工具时&#xff0c;可以从很多方面进行考量、对比…

【历史上的今天】7 月 20 日:人类登上月球;数据仓库之父诞生;Mac OS X Lion 发布

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 7 月 20 日&#xff0c;在 2005 年的今天&#xff0c;时任微软全球副总裁的李开复加盟谷歌担任谷歌全球副总裁及中国区总裁。谷歌公司在发布聘请李开复消息的同…

Debezium系列之:Debezium实现对中文版SQLServer数据库数据采集的支持

Debezium系列之:Debezium实现对中文版SQLServer数据库数据采集的支持 一、背景二、Debezium实现采集SQLSever数据库数据三、验证SQL Server Agent的状态四、中文版SQLServer数据库的支持五、完整配置一、背景 Debezium2.X版本对中文版SQLServer数据库数据库的支持存在一定问题…

LiveNVR监控流媒体Onvif/RTSP功能-拉转Onvif/RTSP/RTMP/FLV/HLS直播流流媒体服务视频广场页面集成视频播放集成说明

LiveNVR拉转Onvif/RTSP/RTMP/FLV/HLS直播流流媒体服务视频广场页面集成视频播放集成说明 1、视频页面集成1.1、关闭接口鉴权1.2、视频广场页面集成1.2.1、隐藏菜单栏1.2.2、隐藏播放页面分享连接 1.3、其它页面集成 2、播放分享页面集成2.1、获取 iframe 代码2.2、html 集成ifr…

Hive 中 sort by 和 order by 的区别

order by会对输入做全局排序&#xff0c;因此只有1个reducer&#xff08;多个reducer无法保证全局有序&#xff09;&#xff0c;会导致当输入规模较大时&#xff0c;需要较长的计算时间。 sort by不是全局排序&#xff0c;其在数据进入 reducer 前完成排序。 因此&#xff0c;…

Java反射的使用

反射是Java框架的核心&#xff0c;无论是Tomcat&#xff0c;SpringMVC&#xff0c;SpringIOC&#xff0c;SpringAOP&#xff0c;动态代理&#xff0c;都使用了反射 那么什么是反射&#xff1f;-------------反射就是获取类信息的能力 Java有两种创建对象的方式&#xff1a;①…

Linux内核的块设备抽象层

Linux内核的块设备抽象层是指块设备框架的核心组件&#xff0c;它负责处理块设备I/O请求&#xff0c;向上层提交完成请求的通知&#xff0c;并提供一些与块设备相关的函数&#xff0c;包括对块设备进行初始化、打开、关闭等操作。 在块设备抽象层中&#xff0c;最基本的结构体…

ffmpeg剪切视频的一些优化(或者说是一些坑)

问题描述 最近我们在做一个项目&#xff0c;这个项目需要使用到ffmpeg这个工具来对视频进行剪切&#xff0c;也就是剪出一个视频中的某一段&#xff0c;在实际测试中&#xff0c;我们发现&#xff0c;ffmpeg剪切速度很慢&#xff0c;而且这个速度还与剪切点开始时间&#xff0…

ThreadPoolExecutor自定义线程池|拒绝策略|线程工厂|统一捕获异常

线程池的7大参数含义介绍 corePoolSize&#xff1a;池中一直保持的线程的数量。 maximumPoolSize&#xff1a;池中允许的最大的线程数。 keepAliveTime&#xff1a;当线程数大于核心线程数的时候&#xff0c;线程在最大多长时间没有接到新任务就会终止释放&#xff0c; 最终…

数据结构--栈和队列

part 1. 栈 栈是一种后进先出的结构。 常用操作&#xff1a; &#xff08;1&#xff09;清空&#xff08;clear&#xff09; &#xff08;2&#xff09;获取栈内元素个数&#xff08;size&#xff09; &#xff08;3&#xff09;判空&#xff08;empty&#xff09; &…