配置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

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-jdbc</artifactId>
     <version>2.7.0</version>
</dependency>
<dependency>
      <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <version>1.18.22</version>
       <scope>provided</scope>
</dependency>
<dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>8.0.28</version>
</dependency>
<dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-boot-starter</artifactId>
       <version>3.5.1</version>
</dependency>
<dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-generator</artifactId>
       <version>3.5.1</version>
</dependency>

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

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

在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.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

package com.kill9.backend.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
}

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

@Mapper
public interface UserMapper extends BaseMapper<User> {

}

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

package com.kill9.backend.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kill9.backend.mapper.UserMapper;
import com.kill9.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
    UserMapper userMapper;
    /**
     * 查询所有用户
     */
    @GetMapping("/user/all/")
    public List<User> getAll(){
        return userMapper.selectList(null);
    }
    /**
     * 查询单个用户
     */
    @GetMapping("/user/{userId}/")
    public User getUser(@PathVariable int userId){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",userId);
        return userMapper.selectOne(queryWrapper);

        // 范围遍历
        // public List<User> getUser(int userId)
        // queryWrapper.ge("id", 2).le("id", 3);
        // return userMapper.selectList(queryWrapper);
    }
    /**
     * 添加某个用户 直接输入 id name password
     * @param userId
     * @param username
     * @param password
     * @return Add User Sucessfully
     */
    @GetMapping("/user/add/{userId}/{username}/")
    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
     * @param userId
     * @return Delete User Successfully
     */
    @GetMapping("/user/delete/{userId}/")
    public String deleteUser(@PathVariable int userId) {
        userMapper.deleteById(userId);
        return "Delete User Successfully";
    }
}

查询user中的全部数据。

 

 

 

查询user中的单个数据。

 

 

添加 user 中的数据。

 

 删除 user 中的数据。

 

3 配置spring security

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

原理解释

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

 

        3.1添加依赖

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

spring-boot-starter-security

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.7.0</version>
</dependency>

刷新之后显示登陆:

 

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

        3.2与数据库对接

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

package com.kill9.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kill9.backend.mapper.UserMapper;
import com.kill9.backend.pojo.User;
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;

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);
    }
}

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

package com.kill9.backend.service.impl.utils;

import com.kill9.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;
    }
}

 

        3.3测试密文

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

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

package com.kill9.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"));
        System.out.println(passwordEncoder.encode("111111"));
    }

}

重启项目,进入login页面

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

 

 

1. 实现密文存储:

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

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

加密算法

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

 

package com.kill9.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() {
        return new BCryptPasswordEncoder();
    }
}

  使用密文添加用户 :

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

  @GetMapping("/user/add/{userId}/{username}/{password}/")
    public String addUser(@PathVariable int userId,
                          @PathVariable String username,
                          @PathVariable String password){
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encodePassword = passwordEncoder.encode(password);
        User user = new User(userId,username,encodePassword);
        userMapper.insert(user);
        return "Add User Successfully";
    }

完成~ 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值