🐍 AcWing SpringBoot - KOB
五、配置 mysql
5.1 下载 &安装
Mysql下载地址:
- 安装:


- 其它页面默认配置即可 ...
5.2 入门操作
配置环境变量:
将
C:\Program Files\MySQL\MySQL Server 8.0\bin( 如果安装到了其他目录,填写相应目录的地址即可)添加到环境变量
PATH中,这样就可以在任意目录的终端中执行mysql命令了。检查是否安装成功 / 是否添加好环境变量(添加到环境变量后):
mysql --versionmysql服务的启动&关闭(默认开机自动启动,如果想手动操作,可以参考如下命令)- 关闭:
net stop mysql80 - 启动:
net stop mysql80
mysqlの 常用操作:连接用户名为
root,密码为123456的数据库服务:mysql -uroot -p123456show databases;:列出所有数据库create database kob;:创建数据库drop database kob;:删除数据库use kob;: 使用数据库kobshow tables;: 列出当前数据库的所有表create table user(id int, username varchar(100)):创建名称为
user的表,表中包含id和username两个属性。drop table user;:删除表insert into user values(1, 'irai');:在表中插入数据select * from user;:查询表中所有数据delete from user where id = 2;:删除某行数据
六、配置 SpringBoot
6.1 地址
6.2 配置 Maven
- 在
pom.xml中添加依赖:Spring Boot Starter JDBCProject LombokMySQL Connector/Jmybatis-plus-spring-boot3-startermybatis-plus-generatorspring-boot-starter-securityjjwt-apijjwt-impljjwt-jackson
6.3 application.properties
- 在
application.properties中添加数据库配置:
spring.datasource.username=root
spring.datasource.password=123456
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.Driver6.4 SpringBoot 简单介绍
SpringBoot中的常用模块pojo层:将数据库中的表对应成Java中的Class(ORM)mapper层(也叫Dao层):将pojo层的class中的操作,映射成sql语句service层:写具体的业务逻辑,组合使用mapper中的操作controller层:负责请求转发,接受页面过来的参数,传给Service处理,接到返回值,再传给页面
6.5 实现用户表的 CRUD
6.5.1 前置工作
- 配置好
Maven的依赖 application.properties的数据库配置也要配置好- 在自己的数据库里创建
kob数据库
create database kob;- 在
kob数据库里创建user这张表
create table user(id int, username varchar(100), password varchar(100));- 在
IDEA可以连接上对应的数据库URL:
jdbc:mysql://localhost:3306/kob?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
6.5.2 pojo
在目录
backend下创建目录pojo,pojo目录下创建User.java这个类我们引入了
lombok这个依赖就可以快速构建pojo:
package com.kob.backend.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
// 对应 sql 里 user 表
private Integer id;
private String username;
private String password;
}6.5.3 Mapper
我们引入了
Mybatis-Plus的依赖,这里我们也可以使用Mybatis-Plus快速构建mapper在目录
backend下创建目录mapper,mapper目录下创建UserMapper这个接口让这个接口继承于
BaseMapper并传入泛型,即BaseMapper<User>就可以让MyBatis-Plus给我们构建好一个关于User的mapper接口了
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> {
}6.5.4 Mybatis-Plus 快速开始
- 对于刚刚我们创建表的语句 :
create table user(id int, username varchar(100), password varchar(100));- 生成几条测试数据:
INSERT INTO user (id, username, password) VALUES
(1, 'admin', 'admin123'),
(2, 'irai', 'irai123'),
(3, 'john', 'john123'),
(4, 'alice', 'alice123'),
(5, 'bob', 'bob123');
❗ 注意:
- 对于在
Maven仓库复制过来的依赖引入,需要重点注意的问题,否则会报错!!!

- 像这种带有
spring-boot的最好就不要添加版本号,让最上面那个依赖统一管理版本:

- 在
6.5.3我们已经编写了user表的mapper,我们添加测试方法进行功能测试:
package com.kob.backend;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class BackendApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userMapper.selectList(null);
userList.forEach(System.out::println);
}
}- 运行结果:

- 这就打印出了
查询所有 User返回的结果 ... ,其实它直接实现了User表的CRUD - 具体参考:BaseMapper Interface
6.5.5 完成 CRUD
接下来我们完成用户表简单的
CRUD接口下面严格来说需要按照三层架构来写,也就是说其实应该有
Service层但是由于逻辑太简单,为了方便调试,只使用
Controller层来完成编写
- 两个重要地址:
- 在
controller目录下创建user目录, 再在user目录下创建UserController
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
// 注入 mapper 层对象
@Autowired
private UserMapper userMapper;
// 查询所有用户信息
@GetMapping("/all/")
public List<User> getAll(){
return userMapper.selectList(null);
}
// 根据 ID 来查找用户
@GetMapping("/{userId}/")
public User getUserById(@PathVariable int userId){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", userId);
// 返回满足条件构造器的一条数据(id 是唯一的)
return userMapper.selectOne(queryWrapper);
}
// 添加一条用户信息
@GetMapping("/add/{userId}/{username}/{password}/")
public String addUser(
@PathVariable int userId,
@PathVariable String username,
@PathVariable String password
){
User user = new User(userId, username, password);
userMapper.insert(user);
return "Add User Successfully";
}
// 根据 Id 删除一条用户信息
@GetMapping("/delete/{userId}")
public String deleteUserById(@PathVariable int userId){
userMapper.deleteById(userId);
return "Delete User Successfully";
}
}- 📌 先叠一波甲:上述很多操作都是不规范的,但目的只是为了快速写个
demo演示Mybatis-Plus
效果:
查找全部用户信息:

- 根据
userid来查找用户:

- 添加一个用户:


- 根据
userid删除一个用户:

6.6 Spring Security
6.6.1 引入 Security
- 在
pom.xml加上依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<!--不要加版本号,让 spring-boot-starter-parent 统一管理-->
<!--<version>...</version>-->
</dependency>重启项目,再访问任意资源文件都会发现访问不到,会被
Spring Security拦截到,并且重定向到了
/login这个路由上, 需要我们输入账号密码:

- 默认的
username是user,而password会在每次运行的时候生成给我们:

- 使用用户名和密码登录后我们就可以正常访问到资源了,然后我们希望登出的话就进入路由
/logout:


可以发现,我们现在进行登录只能用默认用户名和随机生成的密码,如果我们想让
Spring Security对接我们的数据库,也就是说,通过数据库来判断一组用户名密码能不能登录成功,这就需要做相应的配置
6.6.2 配置 Security
实现
service.impl.UserDetailsServiceImpl类,继承自
UserDetailsService接口,用来接入数据库信息操作细节:在
backend目录下创建一个service目录,再在service下创建一个impl目录然后
impl目录下面创建一个UserDetailsServiceImpl类,这个类implements于UserDetailsService这个接口,我们可以alt + ins键快速补全出要实现的方法:

可以发现要我们实现的方法
loadUserByUsername的返回值类型是UserDetails,所以我们还需要写一个类实现
UserDetails: 在impl目录下创建一个utils目录然后在
utils下创建一个类UserDetailsImpl, 也是使用alt + ins键快速补全出实现方法
➡️ UserDetailsServiceImpl
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
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 UsernameNotFoundException("用户不存在");
}
return new UserDetailsImpl(user);
}
}➡️ UserDetailsImpl
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 extends Throwable 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;
}
}但是当我们写好后,即使传入对应数据库的用户名和密码都还是登不进去
那是因为
Spring Security默认只认“用户名 + 加密后的密码”(一般是BCrypt)那么我们需要额外写一个实现用户密码加密存储的类
- 在
backend/config目录下创建一个类SecurityConfig:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}- 关于:
BCryptPasswordEncoder()的两个方法:encode():可以将一个明文转化为密文matches():可以判断传入的某个明文和传入的密文是否匹配
- 那么我们可以在测试方法里试试这两个方法:

- 可以发现,即使我们输入相同的字符串,多次加密的结果也是不一样的
- 但是如果使用匹配
matchs(), 它是可以判断是一样的:

那么有了这个
passwordEncoder()我们就需要在之前UserController里面添加用户信息
addUser那个接口把接收到的明文信息先转化为密文,然后再存储
// 添加一条用户信息
@GetMapping("/add/{userId}/{username}/{password}/")
public String addUser(
@PathVariable int userId,
@PathVariable String username,
@PathVariable String password
){
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodePassword = passwordEncoder.encode(password);
User user = new User(userId, username, encodePassword);
userMapper.insert(user);
return "Add User Successfully";
}之前我们添加的五条用户信息的密码都是明文存的,要不就是从测试方法里一个一个
加密后的密码弄出来,然后手动修改一下,要不就都删掉,使用这个
addUser接口来添加一遍,我就先都删掉,然后加入一条就好了
(想这样操作先注释掉某些刚刚的配置然后使用
user+ 随机密码登录)

添加成功后打开刚刚注释的配置,重新启动项目, 然后使用
irai这个用户来登录这样就既登录进去,又访问到资源信息了:

