文章目录
- 1.MyBatis 是什么?
- 2.回顾 JDBC 的操作流程
- 3.MyBatis 在整个框架中的定位
- 4.MyBatis的使用
- 4.1创建数据库和表
- 4.2 添加MyBatis框架支持
- 4.2.1 老项目添加MyBatis
- 4.2.2 新项目添加MyBatis
- 4.3 配置连接字符串和MyBatis
- 4.3.1 配置连接字符串
- 4.3.2 配置 MyBatis 中的 XML 路径
- 4.4 添加业务代码
- 4.4.1 添加实体类
- 4.4.2 添加 mapper 接口
- 4.4.3 添加 UserMapper.xml
- 4.4.4 添加 Service
- 4.4.5 添加 Controller
- 4.4.6 使用 postman 测试
- 5.增、删、改操作
- 5.1 增加用户操作
- 特殊的添加:返回自增 id
- 5.2 修改用户操作
- 5.3删除操作
- 6.开启mybatis sql日志打印
- 7. @Transactional注解
1.MyBatis 是什么?
MyBatis 是⼀款优秀的持久层框架,它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。 MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和 Java POJO(Plain Old Java Objects,普通⽼式 Java 对象)为数据库中的记录。简单来说 MyBatis 是更简单完成程序和数据库交互的⼯具,也就是更简单的操作和读取数据库⼯具。
Mybatis官网
存储过程:类似方法(包含多条sql/判断/变量声明…)
缺点: 1. 操作难度大 2. 没办法调试 3. 修改和扩展难…
2.回顾 JDBC 的操作流程
- 创建数据库连接池 DataSource
- 通过 DataSource 获取数据库连接 Connection
- 编写要执⾏的带 ? 占位符的 SQL 语句
- 通过 Connection 及 SQL 创建操作命令对象 Statement
- 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
- 使⽤ Statement 执⾏ SQL 语句
- 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
- 处理结果集
- 释放资源
对于 JDBC 来说,整个操作⾮常的繁琐,我们不但要拼接每⼀个参数,⽽且还要按照模板代码的⽅式,⼀步步的操作数据库,并且在每次操作完,还要⼿动关闭连接等,⽽所有的这些操作步骤都需要在每个⽅法中重复书写。
MyBatis 可以帮助我们更⽅便、更快速的操作数据库。
3.MyBatis 在整个框架中的定位
框架交互流程图:
MyBatis 也是⼀个 ORM 框架,ORM(Object Relational Mapping),即对象关系映射。在⾯向对象编程语言中,将关系型数据库中的数据与对象建立起映射关系,进而自动的完成数据与对象的互相转换:
- 将输⼊数据(即传⼊对象)+SQL 映射成原⽣ SQL
- 将结果集映射为返回对象,即输出对象
ORM 把数据库映射为对象:
- 数据库表(table)----> 类(class)
- 记录(record,行数据)-----> 对象(object)
- 字段(field) ----> 对象的属性(attribute)
⼀般的 ORM 框架,会将数据库模型的每张表都映射为⼀个 Java 类。也就是说使用 MyBatis 可以像操作对象⼀样来操作数据库中的表,可以实现对象和数据库表之间的转换。
4.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';
-- 创建⽂章表
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://www.baidu.com', 1);
4.2 添加MyBatis框架支持
添加 MyBatis 框架⽀持分为两种情况:
⼀种情况是对自己之前的 Spring 项目进行升级,另⼀种情况是创建⼀个全新的 MyBatis 和 Spring Boot 的项⽬。
4.2.1 老项目添加MyBatis
添加框架⽀持:
<!-- 添加 MyBatis 框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!-- 添加 MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>runtime</scope>
</dependency>
更简单的操作⽅式是使用EditStarters插件
4.2.2 新项目添加MyBatis
4.3 配置连接字符串和MyBatis
此步骤需要进⾏两项设置,数据库连接字符串设置 和 MyBatis 的 XML ⽂件配置。
4.3.1 配置连接字符串
如果是 application.yml 添加如下内容:
注意空格!!!
# 数据库连接配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
username: root
#注意写自己数据库的密码
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
如果是application.properties添加如下内容:
# 数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
#注意写自己数据库的密码
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
注意事项:
如果使⽤ mysql-connector-java 是 5.x 之前的使⽤的是“com.mysql.jdbc.Driver”
如果是⼤于 5.x使⽤的是“com.mysql.cj.jdbc.Driver”
这里我们使用的是 version5.1.38
4.3.2 配置 MyBatis 中的 XML 路径
MyBatis 的 XML 中保存是查询数据库的具体操作 SQL,配置如下:
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:
mapper-locations: classpath:mybatis/*Mapper.xml
MyBatis组成:
- 接口(表的所有操作方法)
- XML实现接口
4.4 添加业务代码
4.4.1 添加实体类
添加⽤户表:
注意:MySQL中的datetime类型在Java中使用 LocalDateTime
添加用户的实体类:
import lombok.Data;
import java.time.LocalTime;
@Data
public class Userinfo {
//private int id;
private Integer id;
private String username;
private String password;
private String photo;
//注意这里createTime 和updateTime 和数据库中的字段大小写不一样
private LocalDateTime createTime;
private LocalDateTime updateTime;
private int state;
}
4.4.2 添加 mapper 接口
4.4.3 添加 UserMapper.xml
数据持久层的实现,mybatis 的固定 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">
</mapper>
namespace :UserMapper实现哪个mapper接口
xml 实现接口的全路径(包名+接口名)
IDEA插件,实现 mybaits 接口和 xml 的快速定位
UserMapper.xml 查询指定⽤户的具体实现 SQL:
@Mapper
public interface UserMapper {
Userinfo getUserById(@Param("user_id") Integer id);
}
<?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="getUserById" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where id=${user_id}
</select>
</mapper>
以下是对以上标签的说明:
mapper标签:需要指定 namespace 属性,表示命名空间,值为 mapper 接⼝的全限定名,包括全包名.类名。
select查询标签:是⽤来执⾏数据库的查询操作的:
id:是和 Interface(接⼝)中定义的⽅法名称⼀样的,表示对接⼝的具体实现⽅法。
resultType:是返回的数据类型,也就是开头我们定义的实体类。
这里的 ${ } 和#{ } 后面会详细讲解
4.4.4 添加 Service
服务层 UserService 实现代码如下:
@Service
public class UserService {
//属性注入 @Resource或者@Autowired
@Autowired
private UserMapper userMapper;
public Userinfo getUserById(Integer id){
return userMapper.getUserById(id);
}
}
4.4.5 添加 Controller
控制器层 UserController 的实现代码如下:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/getuserid")
public Userinfo getUserById(Integer id){
if(id==null) return null;
return userService.getUserById(id);
}
}
以上代码写完,整个 MyBatis 的查询功能就实现完了,接下来使⽤ postman 来测试⼀下。
4.4.6 使用 postman 测试
userinfo表中的记录:
postman发送请求:
可以看到查询实现效果成功
5.增、删、改操作
实现用户的增加、删除和修改的操作,对应使用 MyBatis 的标签如下:
- insert标签:插⼊语句
- update标签:修改语句
- delete标签:删除语句
5.1 增加用户操作
使用SQL查询创建表结构
show create table userinfo;
创建的userinfo表的表结构:
- 在UserMapper interface中声明方法
- 在mapper.xml中提供实现
注意:赋值使用的是对象中的属性,不是数据库的字段
Userinfo中是createTime 数据库中的字段是createtime
- 单元测试
第一步:在测试类上添加@SpringBootTest
注解
第二步:注入测试对象(这里我们注入UserMapper)
第三步:写单元测试的业务代码
添加成功:
此时拿不到用户的id (自增主键)
因为插入操作默认返回的是影响的行数,不能做到同时返回你要查询的数据。
特殊的添加:返回自增 id
默认情况下返回的是受影响的行数,如果想要返回自增 id,具体实现如下。
UserMapper interface 声明如下:
//添加用户并返回id
int addGetId(Userinfo userinfo);
UserMapper.xml 实现如下:
<insert id="addGetId" useGeneratedKeys="true" keyProperty="id">
insert into userinfo(username,password,createtime,updatetime)
values(#{username},#{password},#{createTime},#{updateTime})
</insert>
●useGeneratedKeys:这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。
●keyColumn:设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第⼀列的时候,是必须设置的。如果⽣成列不止⼀个,可以⽤逗号分隔多个属性名称。
●keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或 insert语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)。如果⽣成列不⽌⼀个,可以⽤逗号分隔多个属性名称。
单元测试:
此时除了影响行数外,还获取到了自增主键 id
5.2 修改用户操作
mapper 接⼝:
int upUser(Userinfo userinfo);
mapper.xml:
<update id="upUser">
update userinfo set username=#{username} where id=#{id}
</update>
单元测试:
结果:
5.3删除操作
mapper 接⼝:
int delById(@Param("id")Integer id);
mapper.xml:
<delete id="delById">
delete from userinfo where id=#{id}
</delete>
6.开启mybatis sql日志打印
在application.properties中加入以下配置:
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
//设置日志级别为debug
logging.level.com.example.demo=debug
执行结果中带有Preparing,Parameters和Updates,更直观的看到 mybatis 执行的sql语句
7. @Transactional注解
单元测试有不污染数据库的功能,使用@Transactional来实现。
工作原理是删除操作后,进行回滚,恢复到原来的数据。
可以加在类前面也可以加在方法前面。
可以看到数据库中的记录没有改变