• 配置Mysql与注册登录模块


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

    数据的来源

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

                    数据的形式
                    数据的操作

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

    数据来源

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

    想要对数据进行各种丰富的处理,需要将数据存放进 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 {
    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 getAll(){
    19. return userMapper.selectList(null);
    20. }
    21. /**
    22. * 查询单个用户
    23. */
    24. @GetMapping("/user/{userId}/")
    25. public User getUser(@PathVariable int userId){
    26. QueryWrapper queryWrapper = new QueryWrapper<>();
    27. queryWrapper.eq("id",userId);
    28. return userMapper.selectOne(queryWrapper);
    29. // 范围遍历
    30. // public List 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. org.springframework.boot
    2. spring-boot-starter-security
    3. 2.7.0

    刷新之后显示登陆:

     

    默认的叫 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 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 Collectionextends 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. }

    完成~ 

  • 相关阅读:
    03-CSS基础选择器
    定位与轨迹-百度鹰眼轨迹开放平台-学习笔记
    决策树,sql考题,30个经典sql题目
    Multisim软件常用仪表的使用与一些基本测量方法
    GIS、多场景加载、溶解特效等功能首次公开,全网免费调用!
    求longhorn winlogon 4074 x64修改过后文件或手动修改方法
    Android监听器中使用AlertDialog导致程序崩溃
    互联网产品知识梳理
    前端版本更新提示
    AI辅助编码体验
  • 原文地址:https://blog.csdn.net/weixin_49884716/article/details/127824214