SpringBoot学习笔记-配置MySQL与实现注册登录模块(上)

  1. 1. SpringBoot配置MySQL
  2. 2. SpringBoot项目模块介绍与构建
    1. 2.1 SpringBoot常用模块介绍
    2. 2.2 构建POJO与Mapper层
    3. 2.3 MyBatis与MyBatis-Plus介绍
    4. 2.4 使用MyBatis-Plus操作数据库
  3. 3. 配置用户认证机制
    1. 3.1 Spring Security对接MySQL
    2. 3.2 密码加密存储

本节内容为实现利用 MyBatis-Plus 配置接入并操作 MySQL 数据库,并集成 Spring Security 进行登录身份的认证。

1. SpringBoot配置MySQL

回顾一下项目的流程,客户端(Clinet)可能会有很多个,每个客户端都会和我们的后端服务器进行通信,一般像我们这种的小项目后端只有一个服务器,项目变大后可能还会做负载均衡。

接下来我们要实现的是用户的注册登录模块,那么在登录的时候就需要将用户的用户名和密码传给服务器,然后服务器再给前端传一些信息回来。显然我们需要将用户的用户名和密码存下来,一般我们会将这些数据存在数据库里,本次项目使用的是 MySQL(安装配置教程可见:MySQL 安装配置与使用教程)。

MySQL 也是一个单独的程序,也可以接收很多请求并返回数据,SpringBoot 与 MySQL 之间也有交互关系,例如根据某个用户名向 MySQL 查询对应的密码等信息。

我们先在终端里登录一下 MySQL:

1
mysql -u root -p

然后创建一个数据库 kob

1
create database kob;

IDEA 是可以图形化操作数据库的,在最右边的选项卡中能够看到数据库(Database),点击 +,在数据源(Data Source)中选择 MySQL,在弹出来的对话框中输入用户名 root 和数据库根用户的密码,数据库输入我们刚创建的 kob,然后点击一下测试连接,第一次连接会让我们下载驱动。在架构选项卡(Schemas)中可以勾上默认架构。最后点击确定即可连接上数据库。

我们创建一个保存用户信息的表 user,然后创建几个字段:idusernamepassword,其类型分别为 intvarchar(100)varchar(100),将 id 设置为自增且非空。创建好后先插入一条数据:(1, "AsanoSaki", "123456")

接下来我们需要加一些依赖,使得 SpringBoot 能够操作数据库。

首先前往 Maven 仓库,搜索并安装以下依赖,一般选择最新版即可,我们将依赖的 Maven 代码复制到 SpringBoot 项目根目录下的 pom.xml 文件的 <dependencies> 代码块中:

  • Spring Boot Starter JDBC
  • Project Lombok
  • MySQL Connector/J
  • mybatis-plus-boot-starter
  • mybatis-plus-generator

复制好后会看到爆红了,在右侧选项卡中打开 Maven,然后点击上方最左侧的刷新(重新加载所有 Maven 项目)按钮 Reload 一遍就行。

然后在 application.properties 文件中添加数据库配置信息:

1
2
3
4
spring.datasource.username=root
spring.datasource.password=<你的数据库根用户密码>
spring.datasource.url=jdbc:mysql://localhost:3306/kob?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

2. SpringBoot项目模块介绍与构建

2.1 SpringBoot常用模块介绍

SpringBoot 中的常用模块有以下几种:

  • pojo 层:将数据库中的表对应成 Java 中的 Class。
  • mapper 层(也叫 Dao 层):将 pojo 层的 Class 中的操作,映射成 SQL 语句。
  • service 层:写具体的业务逻辑,组合使用 mapper 中的操作。
  • controller 层:负责请求转发,接收前端页面传过来的参数,传给 service 处理,接收到返回值后再传给前端页面。

数据库中的表就类似于 Java 中的 Class,pojo 层就是将表转化成 Class,例如我们有一个类 User,里面有三个变量:idusernamepassword。Class 中可能还有一些方法,例如增删改查,那么 mapper 层就负责将这些方法转化成 SQL 语句。我们很多业务可能并不会只处理一张表,因此 service 层就可能用到多个不同的 mapper 操作来实现某个业务。controller 层就是将前端的请求及参数选择将其传给哪个 service,相当于实现调度功能,然后再将 service 的返回结果返回给前端。

2.2 构建POJO与Mapper层

然后在 com.kob.backend 目录下创建 pojo 包,并在 pojo 包下创建 User 类(注意要和数据库表的名字一样):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.kob.backend.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data // Lombok能够帮我们实现get/set之类的方法
@NoArgsConstructor // 无参构造函数
@AllArgsConstructor // 带所有参数的构造函数
public class User {
@TableId(value = "id", type = IdType.AUTO) // 声明id为自增类型
private Integer id;
private String username;
private String password;
}

继续在 com.kob.backend 目录下创建 mapper 包,并在 mapper 包下创建 UserMapper 类,我们使用的是 MyBatis-Plus,只需要继承其实现好的接口即可:

1
2
3
4
5
6
7
8
package com.kob.backend.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kob.backend.pojo.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {}

2.3 MyBatis与MyBatis-Plus介绍

MyBatis 官方文档:MyBatis Docs

MyBatis-Plus 官网:MyBatis-Plus

ORM(Object-Relational Mapping),即对象关系映射,是一种技术,它允许你使用面向对象的范式来查询和操作数据库中的数据。

在面向对象编程中,我们操作的是对象,这些对象有各种属性和行为;而在关系型数据库中,我们操作的是表,这些表由行和列组成。这两种技术之间的差异,就是所谓的对象-关系不匹配

ORM 框架的作用就是在这两者之间做一个映射,可以将 ORM 看作是连接面向对象编程(OOP)和关系数据库表的层,让我们可以用面向对象的方式来操作数据库。例如,我们可以创建一个对象,并将其属性映射到数据库表的列,然后通过操作这个对象,就可以实现对数据库的增删改查。

MyBatis 是一款用于持久层的、轻量级的半自动化 ORM 框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置查询参数和获取结果集的工作。MyBatis 封装了 JDBC 底层访问数据库的细节,使我们不需要与 JDBC API 打交道就可以访问数据库。

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上做了增强,却不做改变。引入 MyBatis-Plus 不会对现有的 MyBatis 架构产生任何影响。MyBatis-Plus 提供了基本的 CRUD 功能,连 SQL 语句都不需要编写。它还提供了一些很有意思的插件,比如 SQL 性能监控、乐观锁、执行分析等。

两者的区别主要体现在以下几个方面:

  • SQL 语句:在 MyBatis 中,所有 SQL 语句都需要自己编写;而在 MyBatis-Plus 中,由于内置了通用 Mapper 和通用 Service,因此可以实现单表的大部分 CRUD 操作,甚至无需编写 SQL 语句。
  • 实体关系映射:在 MyBatis 中,需要手动解析实体关系映射转换为 MyBatis 内部对象并注入容器;而在 MyBatis-Plus 中,可以自动解析实体关系映射转换为 MyBatis 内部对象并注入容器。
  • Lambda 形式调用:MyBatis 不支持 Lambda 形式调用,而 MyBatis-Plus 支持。
  • 条件构造器:MyBatis-Plus 提供了强大的条件构造器,满足各类使用需求。

2.4 使用MyBatis-Plus操作数据库

我们调试的时候先不把 servicecontroller 分开,直接先在 controller 中实现。

我们在 controller 包下创建 userrecordranklist 包,本次实现的注册登录模块在 user 包中实现,因此我们先在 user 包下创建 UserController 类,来看一下如何操作数据库,先实现查询 user 表中的所有数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.kob.backend.controller.user;

import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
@Autowired // 如果要用到数据库里的Mapper需要加上该注解
UserMapper userMapper;

@GetMapping("/user/all/") // 想验证GET/POST类型的请求可以使用GetMapping/PostMapping
public List<User> getAllUser() {
return userMapper.selectList(null); // null表示查询所有数据
}
}

这时我们访问 http://localhost:3000/user/all/ 即可看到返回结果如下:

1
2
3
4
5
6
7
[
{
"id": 1,
"username": "AsanoSaki",
"password": "123456"
}
]

然后我们再尝试通过用户的 ID 查询用户信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.kob.backend.controller.user;

import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
@Autowired // 如果要用到数据库里的Mapper需要加上该注解
UserMapper userMapper;

...

@GetMapping("/user/{id}/") // 根据id查询用户
public User getUser(@PathVariable int id) {
return userMapper.selectById(id);
}
}

访问 http://localhost:3000/user/1/ 即可看到返回结果如下:

1
2
3
4
5
{
"id": 1,
"username": "AsanoSaki",
"password": "123456"
}

我们先理一下执行流程,假设用户访问了链接 http://localhost:3000/user/1/,那么就向后端的 SpringBoot 发出了请求,SpringBoot 根据请求的路径找到所调用的函数 getUser()(由 UserController 类实现),在该函数中使用 UserMapper 类向 MySQL 查询 user 表(由 User 类实现)中 id 为1的用户数据(在这一步操作中会由 MyBatis-Plus 自动转换成类似于 select * from user where id=1; 的 SQL 语句),并将查询结果返回给客户端。

对于复杂的查询语句需要封装一个条件构造器(QueryWrapper),里面有很多 API 可以使用,我们还是和上一步一样实现根据 ID 查询用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.kob.backend.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
@Autowired // 如果要用到数据库里的Mapper需要加上该注解
UserMapper userMapper;

...

@GetMapping("/user/{id}/") // 根据id查询用户
public User getUser(@PathVariable int id) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", id); // 根据链接传入的id查询用户
return userMapper.selectOne(queryWrapper);
}
}

为了更好地测试查询操作,我们再插入几条数据:

1
2
3
(2, "user2", "123")
(3, "user3", "123")
(4, "user4", "123")

然后我们根据 ID 的范围来查询满足条件的所有用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.kob.backend.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
@Autowired // 如果要用到数据库里的Mapper需要加上该注解
UserMapper userMapper;

...

@GetMapping("/user/{id_low}-{id_high}/") // 根据id的范围查询用户
public List<User> getUser(@PathVariable int id_low, @PathVariable int id_high) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("id", id_low).lt("id", id_high); // 查询id大于等于id_low且小于id_high的用户
return userMapper.selectList(queryWrapper); // 此处会返回多个用户
}
}

这时候我们访问 http://localhost:3000/user/2-4/ 即可查询 ID 大于等于2且小于4的所有用户,返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
[
{
"id": 2,
"username": "user2",
"password": "123"
},
{
"id": 3,
"username": "user3",
"password": "123"
}
]

插入与删除数据一般使用 POST,这样就不是明文传输,较为安全,但是为了方便调试我们使用 GET,由于我们的 ID 设置为自增类型,因此我们创建新用户时只需要设置 usernamepassword 即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.kob.backend.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
@Autowired // 如果要用到数据库里的Mapper需要加上该注解
UserMapper userMapper;

...

@GetMapping("/user/insert/{username}/{password}/")
public String insertUser(@PathVariable String username, @PathVariable String password) {
User user = new User();
user.setUsername(username);
user.setPassword(password);
userMapper.insert(user);
return "Add User Successfully!";
}
}

接下来我们再尝试一下删除用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.kob.backend.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
@Autowired // 如果要用到数据库里的Mapper需要加上该注解
UserMapper userMapper;

...

@GetMapping("/user/delete/{id}")
public String deleteUser(@PathVariable int id) {
userMapper.deleteById(id);
return "Delete User Successfully!";
}
}

3. 配置用户认证机制

3.1 Spring Security对接MySQL

我们未来可能有很多操作不能让用户随便访问,需要登录成功后有授权了才可以访问,因此我们要给网站加上授权机制。比如某个用户想查看一个 Bot 的代码,那么我们需要判断这个用户是不是这个 Bot 的作者,如果不是则没有权限查询。

SpringBoot 中也具有权限判断模块 Spring Security,我们将其集成过来,先去 Maven 仓库搜索并安装依赖 spring-boot-starter-security,同样还是将其 Maven 配置代码复制到 pom.xml 文件的 <dependencies> 代码块中,然后别忘了重新加载 Maven。

现在我们再访问之前的 URL 会发现要我们登录,Spring Security 默认的用户名为 user,密码每次启动项目会重新生成,在项目控制台的输出中可以看到 Using generated security password: xxx 的信息,我们登录后即可正常访问之前的那些 URL。

一般网站的验证方式都是通过 Session 实现,当客户端将用户名和密码传给 SpringBoot 后,SpringBoot 会在数据库中查询是否正确,如果正确那么就会将结果返回给客户端,且会在 Session 中传一串随机字符串 SessionID,在传给客户端之前会先将 SessionID 存下来,可以存到 MySQL 也可以是 Redis 中。客户端拿到 SessionID 后会将其存到浏览器的 Cookie 中,Cookie 可以认为是浏览器自带的一个存储空间,浏览器关闭后仍然存在。未来每次再向后端发送请求时客户端都会默认从 Cookie 中取出 SessionID,然后放到 Session 中传给 SpringBoot,SpringBoot 会看一下数据库中是否存在这个 SessionID,且数据库中除了存放 SessionID 之外还会存放对应的用户名、上一次获取 SessionID 的时间等信息,如果没有过期,那么就表示登录成功,如果过期了或者 SessionID 不存在,那么就会给客户端返回一个登录页面。

另一种验证方式是 JWT,可以不需要生成 SessionID 且不需要在数据库中存储数据就实现前后端分离验证,在之后会讲到。

现在来看看如何让 Spring Security 对接我们的 MySQL 数据库,即通过数据库来判断用户是否登录。我们需要配置一下 Spring Security,首先在 com.kob.backend 包下创建一个 service.impl 包(注意有两层),然后在 impl 包下创建一个 UserDetailsServiceImpl 类(类名无所谓,一般习惯这么写),继承自 UserDetailsService 接口。

在 IDEA 中按 Alt + Insert 键可以方便查找接口中的所有方法,我们要重写(Override)loadUserByUsername 方法,该方法会传入一个 username,然后我们要返回对应的用户信息,因此就涉及到了数据库操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.kob.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import com.kob.backend.service.impl.utils.UserDetailsImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service // 表示这是一个Service层
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserMapper userMapper;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", username);
User user = userMapper.selectOne(queryWrapper);
if (user == null) {
throw new RuntimeException("用户不存在");
}
return new UserDetailsImpl(user);
}
}

其中 UserDetailsImpl 类我们定义在 utils 包中(这个包也创建在 impl 包下):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.kob.backend.service.impl.utils;

import com.kob.backend.pojo.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDetailsImpl implements UserDetails {
private User user;

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}

@Override
public String getPassword() {
return user.getPassword();
}

@Override
public String getUsername() {
return user.getUsername();
}

@Override
public boolean isAccountNonExpired() { // 账户是否还没过期
return true;
}

@Override
public boolean isAccountNonLocked() { // 是否没被锁定
return true;
}

@Override
public boolean isCredentialsNonExpired() { // 授权是否还有效
return true;
}

@Override
public boolean isEnabled() { // 用户是否被启用
return true;
}
}

现在我们就可以根据用户输入的用户名在数据库中查询该用户的用户名和密码,再判断密码是否匹配。但是我们尝试一下登录会发现报错说我们没有 PasswordEncoder,因为我们的密码是明文,如果想要调试的话可以先去数据库中给密码加上 {noop} 前缀表示这个密码没有加密,例如:{noop}123456,然后再尝试登录即可登录成功。

3.2 密码加密存储

目前各种各样的加密算法包括之后要讲的 JWT 都有一个特性,就是给我们一个字符串,可以很快地将其变为一个新的字符串,且无法反向求得原始字符串(不可逆),这样假如数据库泄露了也不会将用户的密码泄露出去。

我们实现一个 config.SecurityConfig 类(config 包是在之前解决跨域问题时创建的),即可实现用户密码的加密存储:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kob.backend.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() { // Security会调用该函数
return new BCryptPasswordEncoder(); // 返回某种加密方法,我们使用的是BCrypt方法
}
}

在 Spring Security 中,PasswordEncoder 用于在保存用户密码到数据库时对其进行加密,以及在验证用户提供的密码时对其进行比较。

其中 BCryptPasswordEncoder 常见的有以下几种方法:

  • encode():将明文转换成密文。
  • matches():判断明文和密文是否匹配。

现在我们再尝试登录就无法登录了,我们先在测试文件中把数据库中的密码加密一下,然后手动修改数据库中的密码,系统自带的测试文件是 src/test/java/com.kob.backend 中的 BackendApplicationTests.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kob.backend;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@SpringBootTest
class BackendApplicationTests {
@Test
void contextLoads() {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
System.out.println(passwordEncoder.encode("123456"));
// 输出:$2a$10$CxkFyAQ4juS2uxKzEhaQ0e1IOngp4prEUAPVnygXm2SCuzGHnRWuK
}
}

将数据库中的密码改成密文后又可以正常登录了。

之前在 UserController 中实现的注册用户的功能(insertUser 方法)需要修改为存储加密后的密码,直接放上目前 UserController 的完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.kob.backend.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
@Autowired // 如果要用到数据库里的Mapper需要加上该注解
UserMapper userMapper;

@GetMapping("/user/all/") // 想验证GET/POST类型的请求可以使用GetMapping/PostMapping
public List<User> getAllUser() {
return userMapper.selectList(null); // null表示查询所有数据
}

@GetMapping("/user/{id}/") // 根据id查询用户
public User getUser(@PathVariable int id) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", id); // 根据链接传入的id查询用户
return userMapper.selectOne(queryWrapper);
}

@GetMapping("/user/insert/{username}/{password}/") // 添加用户
public String insertUser(@PathVariable String username, @PathVariable String password) {
if (password.length() < 6) {
return "The length of password should greater than 6!";
}
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(password);
User user = new User();
user.setUsername(username);
user.setPassword(encodedPassword);
userMapper.insert(user);
return "Add User Successfully!";
}

@GetMapping("/user/delete/{id}") // 删除用户
public String deleteUser(@PathVariable int id) {
userMapper.deleteById(id);
return "Delete User Successfully!";
}
}