飞道的博客

配置Mysql与注册登录模块

480人阅读  评论(0)

后端职责可以粗浅的理解为处理各种数据,那么处理数据就可以从下面几个方面考虑:

数据的来源

         根据不同的数据来源,我们探究两个方面的内容:

                数据的形式
                数据的操作

当然,一通操作以后,各个来源的数据需要通信,所以还有一个:数据的交互

数据来源

想要持久化存储数据,需要将数据存入数据库。

想要对数据进行各种丰富的处理,需要将数据存放进 Java 的各种数据结构中(List、Map…)。

还有一个来源就是用户在前端的输入。

1. 数据库
数据形式: 关系型数据库里面的存储可以见到的组织形式就是表。

数据操作: SQL 语言

2. Java 后端
数据形式: 类,数据结构

数据操作: 方法调用

3. 前端
数据形式: 字符串,JSON

数据操作: JavaScript

数据的交互

数据的来源有三个,一般都是以 Java 后端作为中间桥梁。我们一对一对的看。数据交互要达到的效果就是统一形式、互相操作。

 数据库与 Java 后端:

数据库一般只是用来提供数据,所以交互的任务就落到了 Java 后端的身上。

数据库里面数据组织的形式是表,Java 里面是类,因为我们要把数据拿到 Java 里面去操作。一个很自然的想法就是,将表直接映射成 Java 里面的类,由于类只是一个结构,我们具体操作的是类的对象。所以我们更多地会说成将表映射成对象。由于这里的表特指关系型数据库的表,所以这种映射被称为 Object–relational mapping,即对象关系映射,简称 ORM.

那么表能变成对象吗?我们发现是可以的。因为表里的各个属性可以映射到对象的属性上来,每一条表的记录都可以映射成一个对象的各个属性 

理论上是可行的,那实际操作呢?Java 要想将表的记录转变成对象,那就只能通过一系列方法的执行来做到了。

Java 程序员甚至不需要懂 SQL,就完成了和数据库的交互。可以概括如下:

        定义实体类
        写接口
        调用接口

但是默认的这些方法所能够拥有的功能是有限的,对于国内的互联网公司来说,业务可能会十分复杂,数据访问量也会比较大,这时候良好的 SQL 可能就是必要的啦。虽然说 Spring Data JPA 支持自定义 SQL,但是这不是它的长处,在某些情境下是要受到限制的。于是虽然世界上整体流行使用 JPA,但是我们国内用的不多。

于是我们需要一种对 SQL 支持良好的框架,程序员的注意力可以从写 Java 代码转到了写 SQL 上。这款框架就是 MyBatis.

那么 MyBatis 的步骤就是多了几步:

        定义实体类
        写接口
        写 SQL
        接口与 SQL 绑定
        调用接口

在 MyBatis 官方文档里有这样几句话:

MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美适配所有的应用程序,那就太好了,但可惜也没有。 而 ResultMap 就是 MyBatis 对这个问题的答案。

 MyBatis Plus. 它在 MyBatis 的基础上增加了一些常用的接口和功能。并且还有一个神奇的代码生成器,只需要在图形界面点两下,代码和映射文件都会帮你生成好,连代码都不需要写了。

后端对数据的处理

不管你是用什么方式从数据库拿到的数据,在 Java 里面就是一个个对象,这时候就可以拿 Java 语言对数据进行各种操作咯。那么处理完成以后,你还需要返回给前端

前后端数据交互

既然要返回给前端,那么数据形式仍然要统一。前端可以认识的形式就是 JSON,所以我们需要把 Java 对象转换成 JSON,数据格式如果统一的话,那么我们还要想的就是前后端如何通信。

前端每一个请求都对应一个URL,我们将 URL 和 Java 的方法建立映射,一旦在前端访问到 URL,我们就执行相应的后端方法处理相应的请求。

而这些工作在 Spring Boot 里面都有了很好的支持,我们通常使用注解来进行实现。

当然前端也可以发送 JSON 格式的数据给后端,后端转换为 Java 对象,再通过 ORM 框架完成存入数据库的操作。

后端分层的依据

我们可以看到,Java 后端承载着太多的使命:

        数据库访问
        数据处理
        前后端交互


那么将每一项使命放在不同的包里,就对应的变成了 dao 层、service 层和 controller 层。

应用模型:

springboot 的角色是用来处理用户请求的,从client端向springboot端发送请求,然后向数据库请求数据,数据库返回数据给前端

1 idea连接mysql

点击右边的数据库 -> + -> 数据源-> MySQL,输入账号、密码、数据库名称,这里是kob,点击测试连接,成功后点击应用就可以了。

创建数据库 kill9 

create database kill9;

2 配置springboot

        2.1添加依赖和数据库配置

添加依赖

在pom.xml下添加依赖,依赖可以 Maven仓库地址 中寻找。
        Spring Boot Starter JDBC
        Project Lombok
        MySQL Connector/J
        mybatis-plus-boot-starter
        mybatis-plus-generator


  
  1. <dependency>
  2. <groupId>org.springframework.boot </groupId>
  3. <artifactId>spring-boot-starter-jdbc </artifactId>
  4. <version>2.7.0 </version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.projectlombok </groupId>
  8. <artifactId>lombok </artifactId>
  9. <version>1.18.22 </version>
  10. <scope>provided </scope>
  11. </dependency>
  12. <dependency>
  13. <groupId>mysql </groupId>
  14. <artifactId>mysql-connector-java </artifactId>
  15. <version>8.0.28 </version>
  16. </dependency>
  17. <dependency>
  18. <groupId>com.baomidou </groupId>
  19. <artifactId>mybatis-plus-boot-starter </artifactId>
  20. <version>3.5.1 </version>
  21. </dependency>
  22. <dependency>
  23. <groupId>com.baomidou </groupId>
  24. <artifactId>mybatis-plus-generator </artifactId>
  25. <version>3.5.1 </version>
  26. </dependency>

选择哪个版本号,都可以,个人习惯是最新的几个版本里选用的人最多的版本。

点击 maven 的重新加载,刷新 Maven。

在application.properties中添加数据库配置:


  
  1. //输入你自己的用户和密码
  2. spring.datasource.username=root
  3. spring.datasource.password= 123456
  4. spring.datasource.url=jdbc:mysql: //localhost:3306/kob?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
  5. spring.datasource.driver- class- name=com.mysql.cj.jdbc.Driver

点击运行 出现报错 可能是因为路径问题。
点击运行,输入网址 http://127.0.0.1:8080/pk/index/ 显示界面就成功了 

        2.2实现简单的crud

SpringBoot中的常用模块:

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

 注解:

使用注解可以帮助我们不在需要配置繁杂的xml文件,以前最基本的web项目是需要写xml配置的,需要标注你的哪个页面和哪个 servle 是对应的,注解可以帮助我们减少这方面的麻烦。

@Controller:用于定义控制器类,在spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层),一般这个注解在类中,通常方法需要配合注解@RequestMapping。

@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。

@Autowired:自动导入依赖的bean

@Service:一般用于修饰service层的组件

@Bean:用@Bean标注方法等价于XML中配置的bean。

@AutoWired:自动导入依赖的bean。byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。

在 backend 下创建 pojo 包 创建一个类 User,将数据库中的表 User转化为 Java 中的 User.class


  
  1. package com.kill9.backend.pojo;
  2. import lombok.Data;
  3. import lombok.NoArgsConstructor;
  4. import lombok.AllArgsConstructor;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class User {
  9. private Integer id;
  10. private String username;
  11. private String password;
  12. }

 在backend创建mapper 包,创建一个 Java 类的接口 UserMapper


  
  1. @Mapper
  2. public interface UserMapper extends BaseMapper<User> {
  3. }

在backend 的 controller 下创建 user 包然后创建 UserController.


  
  1. package com.kill9.backend.controller.user;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.kill9.backend.mapper.UserMapper;
  4. import com.kill9.backend.pojo.User;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.web.bind.annotation.GetMapping;
  7. import org.springframework.web.bind.annotation.PathVariable;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import java.util.List;
  10. @RestController
  11. public class UserController {
  12. @Autowired
  13. UserMapper userMapper;
  14. /**
  15. * 查询所有用户
  16. */
  17. @GetMapping("/user/all/")
  18. public List<User> getAll (){
  19. return userMapper.selectList( null);
  20. }
  21. /**
  22. * 查询单个用户
  23. */
  24. @GetMapping("/user/{userId}/")
  25. public User getUser (@PathVariable int userId){
  26. QueryWrapper<User> queryWrapper = new QueryWrapper<>();
  27. queryWrapper.eq( "id",userId);
  28. return userMapper.selectOne(queryWrapper);
  29. // 范围遍历
  30. // public List<User> getUser(int userId)
  31. // queryWrapper.ge("id", 2).le("id", 3);
  32. // return userMapper.selectList(queryWrapper);
  33. }
  34. /**
  35. * 添加某个用户 直接输入 id name password
  36. * @param userId
  37. * @param username
  38. * @param password
  39. * @return Add User Sucessfully
  40. */
  41. @GetMapping("/user/add/{userId}/{username}/")
  42. public String addUser (@PathVariable int userId,
  43. @PathVariable String username,
  44. @PathVariable String password){
  45. User user = new User(userId,username,password);
  46. userMapper.insert(user);
  47. return "Add User Successfully";
  48. }
  49. /**
  50. * 删除某个用户,直接输入 id
  51. * @param userId
  52. * @return Delete User Successfully
  53. */
  54. @GetMapping("/user/delete/{userId}/")
  55. public String deleteUser (@PathVariable int userId) {
  56. userMapper.deleteById(userId);
  57. return "Delete User Successfully";
  58. }
  59. }

查询user中的全部数据。

 

 

 

查询user中的单个数据。

 

 

添加 user 中的数据。

 

 删除 user 中的数据。

 

3 配置spring security

 是用户认证操作 – 一种授权机制,目的是安全。

原理解释

数据库可以知道sessionId对应的用户是谁
如果想让我们的security对接我们的数据库
需要把username在数据库中对应的的用户找出来,返回他的密码
需要用到数据库操作mapper,能写private就写private,用数据库记得加上autowired

 

        3.1添加依赖

1. 添加依赖,添加之后刷新。

spring-boot-starter-security


  
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-security</artifactId>
  4. <version> 2.7 .0</version>
  5. </dependency>

刷新之后显示登陆:

 

默认的叫 Username 是 user ,密码自动生成。

        3.2与数据库对接

在backend 的 service 创建 impl 包,新建 UserDetailsServiceImpl 类。
实现service.impl.UserDetailsServiceImpl类,继承自UserDetailsService接口,用来接入数据库信息。


  
  1. package com.kill9.backend.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.kill9.backend.mapper.UserMapper;
  4. import com.kill9.backend.pojo.User;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.security.core.userdetails.UserDetails;
  7. import org.springframework.security.core.userdetails.UserDetailsService;
  8. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  9. public class UserDetailsServiceImpl implements UserDetailsService {
  10. @Autowired
  11. private UserMapper userMapper;
  12. @Override
  13. public UserDetails loadUserByUsername (String username) throws UsernameNotFoundException {
  14. QueryWrapper<User> queryWrapper = new QueryWrapper<>();
  15. queryWrapper.eq( "username",username);
  16. User user = userMapper.selectOne(queryWrapper);
  17. if(user== null){
  18. throw new RuntimeException( "用户不存在");
  19. }
  20. return new UserDetailsImpl(user);
  21. }
  22. }

在backend 的 service 包的 impl 包下创建utils 包 新建 UserDetailsImpl。 


  
  1. package com.kill9.backend.service.impl.utils;
  2. import com.kill9.backend.pojo.User;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5. import lombok.NoArgsConstructor;
  6. import org.springframework.security.core.GrantedAuthority;
  7. import org.springframework.security.core.userdetails.UserDetails;
  8. import java.util.Collection;
  9. @Data
  10. @NoArgsConstructor
  11. @AllArgsConstructor
  12. public class UserDetailsImpl implements UserDetails {
  13. private User user;
  14. @Override
  15. public Collection<? extends GrantedAuthority> getAuthorities() {
  16. return null;
  17. }
  18. @Override
  19. public String getPassword () {
  20. return user.getPassword();
  21. }
  22. @Override
  23. public String getUsername () {
  24. return user.getUsername();
  25. }
  26. @Override
  27. public boolean isAccountNonExpired () {
  28. return true;
  29. }
  30. @Override
  31. public boolean isAccountNonLocked () {
  32. return true;
  33. }
  34. @Override
  35. public boolean isCredentialsNonExpired () {
  36. return true;
  37. }
  38. @Override
  39. public boolean isEnabled () {
  40. return true;
  41. }
  42. }

 

        3.3测试密文

如果实现登录的话,需要提供一个 PassworEncoder。
如果在数据库中指定明文来存储,需要在自己的密码加上{noop},才可以登录。

在 Test 下生成需要转换的密文,同时修改数据库下的密码为密文


  
  1. package com.kill9.backend;
  2. import org.junit.jupiter.api.Test;
  3. import org.springframework.boot.test.context.SpringBootTest;
  4. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  5. import org.springframework.security.crypto.password.PasswordEncoder;
  6. @SpringBootTest
  7. class BackendApplicationTests {
  8. @Test
  9. void contextLoads () {
  10. PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
  11. System.out.println(passwordEncoder.encode( "123456"));
  12. System.out.println(passwordEncoder.encode( "111111"));
  13. }
  14. }

重启项目,进入login页面

登录成功,只要不给你显示密码错误就代表成功,显示Whitelabel Error Page也是成功,自己在后面添加路径就可以了登录。

 

 

1. 实现密文存储:

上传之后就能登录,数据库知道没有加密之后就不会用到PasswordEncoder
实现任何用户都可以登录

在 config 下新建 SecurityConfig 。
实现config.SecurityConfig类,用来实现用户密码的加密存储。

加密算法

如果不明文我们可以,将左边哈希到右边,就算数据库泄露我们也不会泄露用户密码

 


  
  1. package com.kill9.backend.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  5. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  6. import org.springframework.security.crypto.password.PasswordEncoder;
  7. @Configuration
  8. @EnableWebSecurity
  9. public class SecurityConfig {
  10. @Bean
  11. public PasswordEncoder passwordEncoder () {
  12. return new BCryptPasswordEncoder();
  13. }
  14. }

  使用密文添加用户 :

修改 controller 下的 user 的 UserController的注册,密码直接存储加密之后的密码。


  
  1. @GetMapping("/user/add/{userId}/{username}/{password}/")
  2. public String addUser (@PathVariable int userId,
  3. @PathVariable String username,
  4. @PathVariable String password){
  5. PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
  6. String encodePassword = passwordEncoder.encode(password);
  7. User user = new User(userId,username,encodePassword);
  8. userMapper.insert(user);
  9. return "Add User Successfully";
  10. }

完成~ 


转载:https://blog.csdn.net/weixin_49884716/article/details/127824214
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场