MyBatis查询数据库

MyBatis 是什么

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

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

为什么要学习 MyBatis

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

  • 后端程序
  • 数据库

在这里插入图片描述

⽽这两个重要的组成部分要通讯,就要依靠数据库连接⼯具,那数据库连接⼯具有哪些?⽐如之前我们学习的 JDBC,还有今天我们将要介绍的 MyBatis,那已经有了 JDBC 了,为什么还要学习 MyBatis?这是因为 JDBC 的操作太繁琐了,我们回顾⼀下 JDBC 的操作流程:

  1. 创建数据库连接池 DataSource
  2. 通过 DataSource 获取数据库连接 Connection
  3. 编写要执⾏带 ? 占位符的 SQL 语句
  4. 通过 Connection 及 SQL 创建操作命令对象 Statement
  5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
  6. 使⽤ Statement 执⾏ SQL 语句
  7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
  8. 处理结果集
  9. 释放资源

由于JDBC整个操作流程太复杂,于是我们就想,那有没有⼀种⽅法,可以更简单、更⽅便的操作数据库呢?这就是我们要学习 MyBatis 的真正原因,它可以帮助我们更⽅便、更快速的操作数据库。

怎么学MyBatis

MyBatis 学习分为两部分:

  1. 配置 MyBatis 开发环境
  2. 使⽤ MyBatis 模式和语法操作数据库

第⼀个MyBatis查询

开始搭建 MyBatis 之前,我们先来看⼀下 MyBatis 在整个框架中的定位,框架交互流程图:

在这里插入图片描述

MyBatis 也是⼀个 ORM 框架,ORM(Object Relational Mapping),即对象关系映射。在⾯向对象编程语⾔中,将关系型数据库中的数据与对象建⽴起映射关系,进⽽⾃动的完成数据与对象的互相转换

  1. 将输⼊数据(即传⼊对象)+SQL 映射成原⽣ SQL
  2. 将结果集映射为返回对象,即输出对象

ORM 把数据库映射为对象:

  • 数据库表(table)–> 类(class)
  • 记录(record,⾏数据)–> 对象(object)
  • 字段(field) --> 对象的属性(attribute)

⼀般的 ORM 框架,会将数据库模型的每张表都映射为⼀个 Java 类。
也就是说使⽤ MyBatis 可以像操作对象⼀样来操作数据库中的表,可以实现对象和数据库表之间的转换,接下来我们来看 MyBatis 的使⽤吧

创建数据库和表

接下来我们要实现的功能是:使⽤ MyBatis 的⽅式来读取⽤户表中的所有⽤户,具体 SQL 如下

-- 创建数据库
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';
-- 创建⽂章表
drop table if exists articleinfo;
create table articleinfo(
                            id int primary key auto_increment,
                            title varchar(100) not null,
                            content text not null,
                            createtime datetime default now(),
                            updatetime datetime default now(),
                            uid int not null,
                            rcount int not null default 1,
                            `state` int default 1
)default charset 'utf8mb4';
-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(
                          vid int primary key,
                          `title` varchar(250),
                          `url` varchar(1000),
                          createtime datetime default now(),
                          updatetime datetime default now(),
                          uid int
)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)
;
-- ⽂章添加测试数据
insert into articleinfo(title,content,uid)
values('Java','Java正⽂',1);

-- 添加视频
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://ww
w.baidu.com',1);

添加MyBatis框架⽀持

添加 MyBatis 框架⽀持分为两种情况:⼀种情况是对⾃⼰之前的 Spring 项⽬进⾏升级,另⼀种情况是创建⼀个全新的 MyBatis 和 Spring Boot 的项⽬,下⾯我们分别来演示这两种情况的具体实现

新项⽬添加MyBatis

如果是新项⽬创建 Spring Boot 项⽬的时候添加引⽤就可以了,如下图所示:

在这里插入图片描述

设置MyBatis配置信息

此步骤需要进⾏两项设置,数据库连接字符串设置和 MyBatis 的 XML ⽂件配置

设置数据库连接相关信息

如果是 application.properties 添加如下内容:
在这里插入图片描述

MyBatis XML 保存路径和 XML命名模式

MyBatis 的 XML 中保存是查询数据库的具体操作 SQL,配置如下:

在这里插入图片描述

Mybatis模式开发

有两部分组成

  1. interface:让其他层可以注入使用的接口
  2. mybatis:xml具体实现SQL,也就是interface的实现

在这里插入图片描述

添加实体类

先添加⽤户的实体类:
在这里插入图片描述

添加 mapper 接⼝

数据持久层的接⼝定义:
在这里插入图片描述

添加 UserMapper.xml

数据持久成的实现,mybatis 的固定 xml 格式:

<?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.demo.mapper.UserMapper">
 
</mapper>

UserMapper.xml 查询所有⽤户的具体实现 SQL:
在这里插入图片描述

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

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

添加 Service

服务层实现代码如下:

在这里插入图片描述

添加 Controller

控制器层的实现代码如下:

在这里插入图片描述

以上代码写完,整个 MyBatis 的查询功能就实现完了,接下来使⽤ postman 来测试⼀下

使⽤ postman 测试

在这里插入图片描述

使用单元测试

在这里插入图片描述

测试结果如下:

在这里插入图片描述

查询操作

单表查询

下⾯我们来实现⼀下根据⽤户 id 查询⽤户信息的功能
Controller 实现代码如下:

在这里插入图片描述

Mapper.xml 实现代码如下:
在这里插入图片描述

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

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

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

使用单元测试进行演示
在这里插入图片描述

参数占位符 ${}
在这里插入图片描述

参数占位符 #{}
在这里插入图片描述

${} 优点

使⽤ ${sort} 可以实现排序查询,⽽使⽤ #{sort} 就不能实现排序查询了,因为当使⽤ #{sort} 查询时,如果传递的值为 String 则会加单引号,就会导致 sql 错误

SQL 注⼊问题

添加 mapper 接⼝
在这里插入图片描述

添加 UserMapper.xml
在这里插入图片描述

单元测试(确保数据库中只有一个数据)
在这里插入图片描述

结果如下
在这里插入图片描述

很奇怪,密码不正确但是却可以获取用户信息,这就是参数占位符 ${} 所带来的问题,原因解释如下

在这里插入图片描述

因此,⽤于查询的字段,尽量使⽤ #{} 预查询的⽅式

like 查询

添加 mapper 接⼝
在这里插入图片描述

添加 UserMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

多表查询

如果是增、删、改返回搜影响的⾏数,那么在 mapper.xml 中是可以不设置返回的类型的;然⽽即使是最简单查询⽤户的名称也要设置返回的类型

返回类型:resultType

绝⼤数查询场景可以使⽤ resultType 进⾏返回,如下代码所示:

在这里插入图片描述

它的优点是使⽤⽅便,直接定义到某个实体类即可

返回字典映射:resultMap

resultMap 使⽤场景:

  • 字段名称和程序中的属性名不同的情况,可使⽤ resultMap 配置映射
  • ⼀对⼀和⼀对多关系可以使⽤ resultMap 映射并查询数据

字段名和属性名不同的情况
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/256baf57afb444f29dc57921a14e122a.png

如果使用resultType进行返回,将获取不到这个字段名

这个时候就可以使⽤ resultMap 了,resultMap 的使⽤如下:
在这里插入图片描述

多表查询

⼀对⼀的表映射

新增文章表
在这里插入图片描述

多表查询时,返回的是用户名称,因此创建VO对象
在这里插入图片描述

添加 mapper 接⼝
在这里插入图片描述

添加 ArticleMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

⼀对多:⼀个⽤户多篇⽂章案例

添加 mapper 接⼝
在这里插入图片描述

添加 ArticleMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

增、删、改操作

接下来,我们来实现⼀下⽤户的增加、删除和修改的操作,对应使⽤ MyBatis 的标签如下:

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

增加⽤户操作

添加 mapper 接⼝
在这里插入图片描述

添加 UserMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:

默认情况下返回的是受影响的⾏数
在这里插入图片描述

特殊的添加:返回⾃增 id

添加 mapper 接⼝

在这里插入图片描述

添加 UserMapper.xml

在这里插入图片描述

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

单元测试

在这里插入图片描述

测试结果如下:
在这里插入图片描述

修改⽤户操作

添加 mapper 接⼝
在这里插入图片描述

添加 UserMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

删除⽤户操作

添加 mapper 接⼝
在这里插入图片描述

添加 UserMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

动态SQL使⽤

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

标签

有时当我们在注册⽤户的时候,可能会有这样⼀个问题,有些选项比如账号,密码属于必填项;还有一些例如年龄,性别属于非必填项

注册分为两种字段:必填字段和⾮必填字段,那如果在添加⽤户的时候有不确定的字段传⼊,程序应该如何实现呢?
这个时候就需要使⽤动态标签 来判断了,⽐如添加的时候个人图片 为⾮必填字段,具体实现如下

添加 mapper 接⼝
在这里插入图片描述

添加 UserMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

标签

之前的插⼊⽤户功能,只是有⼀个 sex 字段可能是选填项,如果所有字段都是⾮必填项,就考虑使⽤标签结合标签,对多个字段都采取动态⽣成的⽅式;可以理解为标签是为了加强标签而存在的

标签中有如下属性:

  • prefix:表示整个语句块,以prefix的值作为前缀
  • suffix:表示整个语句块,以suffix的值作为后缀
  • prefixOverrides:表示整个语句块要去除掉的前缀
  • suffixOverrides:表示整个语句块要去除掉的后缀

添加 mapper 接⼝
在这里插入图片描述

添加 UserMapper.xml
在这里插入图片描述

在以上 sql 动态解析时,会将第⼀个 部分做如下处理:

  • 基于 prefix 配置,开始部分加上 (
  • 基于 suffix 配置,结束部分加上 )
  • 多个 组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于 suffixOverrides 配置去掉最后⼀个 ,

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

标签

传⼊的⽤户对象,根据属性做 where 条件查询,⽤户对象中属性不为 null 的,都为查询条件

添加 mapper 接⼝
在这里插入图片描述

添加 ArticleMapper.xml
在这里插入图片描述

<where>标签会自动去除最前面的and,但不会去除最后面的and

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

标签

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

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

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

添加 mapper 接⼝
在这里插入图片描述

添加 ArticleMapper.xml
在这里插入图片描述

单元测试
在这里插入图片描述

测试结果如下:
在这里插入图片描述

  • 29
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值