公告

记录一下自己学习和生活中的所见所闻

Skip to content

用户中心项目注册功能

参考笔记

https://uold3d6685.feishu.cn/wiki/IOTZwd7g0iS7NOkHCIHcp0q4n8S

✔数据库表设计

  1. 什么是数据库? 存数据的​
  2. 数据库里有什么? 数据表(理解为 excel 表格)​
  3. Java 操作数据库,代替人工​
  4. 什么是设计数据库表?​
  5. 有哪些表(模型)?表中有哪些字段?字段的类型?数据库字段添加索引?表与表之间的关联?

性别是否需要索引?​ 不需要,区分度不高的字段。只有2种取值的字段,建了索引数据库也不一定会用,只会白白增加索引维护的额外开销,因为索引也是需要存储的,所以插入和更新的写入操作,同时需要插入和更新你这个字段的索引的。所以说,唯一性太差的字段不需要创建索引,即便用于where条件

image.png

  1. 删除测试 Mybatis-plus 是否引入成功时创建的 user 表,执行如下语句
SQL
DROP TABLE IF EXISTS `user

image.png

image.png

  1. 建表,执行如下建表语句(或者使用 idea、可视化工具建表)
SQL
CREATE TABLE `user` (​

    `username` varchar(256)                             NULL COMMENT '用户昵称',​
    `id` bigint NOT NULL AUTO_INCREMENT                 COMMENT 'id',​
    `userAccount` varchar(256)                          NULL COMMENT '账号',​
    `avatarUrl` varchar(1024)                           NULL COMMENT '用户头像',​
    `gender` tinyint                                    NULL COMMENT '性别',​
    `userPassword` varchar(512)                         NOT NULL COMMENT '密码',​
    `phone` varchar(128)                                NULL COMMENT '电话',​
    `email` varchar(512)                                NULL COMMENT '邮箱',​
    `userStatus` int DEFAULT '0'                        NULL COMMENT '状态 0-正常',​
    `createTime` datetime DEFAULT CURRENT_TIMESTAMP     NULL COMMENT '创建时间',​
    `updateTime` datetime DEFAULT CURRENT_TIMESTAMP     NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',​
    `isDelete` tinyint  DEFAULT '0'                     NOT NULL COMMENT '是否删除',​
    PRIMARY KEY (`id`)​

) COMMENT='用户表';

image.png

规整项目目录

  • 新建 controller、service、utils 包,删除测试 Mybatis-plus 是否引入成功时创建的 User、UserMapper、SampleTest

一般SpringBoot项目都是比较固定的,每个层干什么都有规范

image.png

【图解 Spring Boot 五层结构】

image.png

image.png

✔注册功能

后端-代码生成器的使用

Mybatis-X插件,自动根据数据库生成 ​

  • domain(实体对象)​
  • mapper(操作数据库的对象)​
  • mapper.xml(定义了mapper对象和数据库的关联,可以在里面自己写SQL)​
  • service(包含常用的增删改查)​
    • serviceImpl(具体实现service)

1. 插件的安装

File -> Settings -> Plugins -> 搜索MyBatisX -> Install​

image.png

2. 插件的使用

image.png

image.png

image.png

image.png

勾选 Comment 可以在生成的实体类添加注释​ 勾选 Actual Column 可以让生成实体类的字段名和数据库保持一致

3. 代码整合​

  • domain 放入 model 包​
  • UserMapper 放入mapper 包​
  • impl 和 UserService 放入 service 包​
  • 删除 generator

4. 测试​

  • 鼠标放在 UserService.java 文件的 UserService 上,按住 alt + enter ,选择创建测试类 image.png

image.png

image.png

  • 编写测试代码【安装插件 CenerateAllSetter ,可快速生成代码】

    • 增加下述代码 image.pngimage.pngimage.png
  • 修改生成的代码(删除带有默认值的字段,剩下的字段增加数据) 设置返回值类型 image.png 增加代码 image.png 完整代码:

java
package com.yupi.usercenter.service;​

import com.yupi.usercenter.model.domain.User;​
import org.junit.jupiter.api.Assertions;​
import org.junit.jupiter.api.Test;​
import org.springframework.boot.test.context.SpringBootTest;​

import javax.annotation.Resource;​

@SpringBootTest
class UserServiceTest {​

@Resource
private UserService userService;​

@Test
void testAddUser() {​
   User user = new User();​
   user.setUsername("dogYupi");​
   user.setUserAccount("123");​
   user.setAvatarUrl("https://profile-avatar.csdnimg.cn/aee7bf7d9b0640489ce4189664a41212_2201_75344078.jpg!1");​
   user.setGender(0);​
   user.setUserPassword("xxx");​
   user.setPhone("123");​
   user.setEmail("456");​
   boolean result = userService.save(user);​
   System.out.println(user.getId());​
   Assertions.assertTrue(result);  // 断言result为true​
}
  • 执行测试,会发现报错 image.png

这里还有一个问题就是生成的代码复制的时候一定要重构项目,否则包名不对,后面就会报错

5. 问题解决

  • 问题原因:MyBatisX自动开启从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射​
  • 问题解决:yml 文件中添加如下配置 官网描述【链接已更新】
SQL
mybatis-plus:​
  configuration:​
    map-underscore-to-camel-case: false
  • 再次测试 image.pngimage.png

image.png

TIP

到这里我们的测试就是成功了,后面我们就要自己写代码了

详细设计

  1. 用户在前端输入账户和密码、以及校验码(todo)​
  2. 校验用户的账户、密码、校验密码是否符合要求 ​
    • 账户不小于 4 位(自己扩展校验)​
    • 密码不小于 8 位​
    • 账户不能重复
    • 账户不包含特殊字符​
    • 密码和校验密码相同​
  3. 对密码进行加密千万不能明文存储到数据库中)​
  4. 向数据库插入用户数据

后端-接口测试开发

TIP

如何快速生成注释​ 在方法上打出 /** 回车即可

image.png

image.png

  1. src/main/java/com/yupi/usercenter/service/UserService.java 编写 userRegister 方法并实现 image.png

  2. 去 maven 仓库 引入 commons-lang3 依赖【记得刷新依赖】

这个库里面有检验的方法,这样就可以不用自己写了,自己写太麻烦了 StringUtils.isAnyBlank 用来判断多个字段是不是为空

XML
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>​
    <groupId>org.apache.commons</groupId>​
    <artifactId>commons-lang3</artifactId>​
    <version>3.12.0</version>​
</dependency>
  1. UserServiceImpl 实现代码
JAVA
package com.yupi.usercenter.service.impl;​

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;​
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;​
import com.yupi.usercenter.model.domain.User;​
import com.yupi.usercenter.service.UserService;​
import com.yupi.usercenter.mapper.UserMapper;​
import org.apache.commons.lang3.StringUtils;​
import org.springframework.stereotype.Service;​
import org.springframework.util.DigestUtils;​

import javax.annotation.Resource;​
import java.util.regex.Matcher;​
import java.util.regex.Pattern;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>​
    implements UserService{​

   @Resource
   private UserMapper userMapper;​

   @Override
   public long userRegister(String userAccount, String userPassword, String checkPassword) {​
      /* 1. 校验 */
      if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {​
         return -1;​
      }​
      if (userAccount.length() < 4) {​
         return -1;​
      }​
      if (userPassword.length() < 8 || checkPassword.length() < 8) {​
         return -1;​
      }
      //账户不能包含特殊字符​
      String validateRegExp = "\\pP|\\pS|\\s+";​
      Matcher matcher = Pattern.compile(validateRegExp).matcher(userAccount);​
      if (!matcher.find()) {​
         return -1;​
      }​

      //校验密码是否相同​
      if (!userPassword.equals(checkPassword)) {​
         return -1;​
      }​

      //账户不能重复​
      QueryWrapper<User> queryWrapper = new QueryWrapper<>();​
      queryWrapper.eq("userAccount", userAccount);​
      Long count = userMapper.selectCount(queryWrapper);​
      if (count > 0) {​
         return -1;​
      }
      /* 2.加密 —— 先做一个测试【如下图所示】 */
      final String SALT = "yupi";​
      String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());​

      /* 3.插入数据 */
      User user = new User();​
      user.setUserAccount(userAccount);​
      user.setUserPassword(encryptPassword);​
      boolean saveResult = this.save(user);​
      if (!saveResult) {​
         return -1;​
      }​

      return user.getId();​
   }
}

src/test/java/com/yupi/usercenter/UserCenterApplicationTests.java 中编写测试,执行(加密成功)

image.png

后端-单元测试

  • ServiceTest 测试代码生成与编写

image.png

image.png

Java
@Test
void userRegister() {​
   String userAccount = "yupi";​
   String userPassword = "";​
   String checkPassword = "123456";​
   long result = userService.userRegister(userAccount, userPassword, checkPassword);​
   Assertions.assertEquals(-1, result);​

   userAccount = "yu";​
   result = userService.userRegister(userAccount, userPassword, checkPassword);​
   Assertions.assertEquals(-1, result);​

   userAccount = "yupi";​
   userPassword = "123456";​
   result = userService.userRegister(userAccount, userPassword, checkPassword);​
   Assertions.assertEquals(-1, result);​

   userAccount = "yu pi";​
   userPassword = "12345678";​
   result = userService.userRegister(userAccount, userPassword, checkPassword);​
   Assertions.assertEquals(-1, result);​

   checkPassword = "123456789";​
   result = userService.userRegister(userAccount, userPassword, checkPassword);​
   Assertions.assertEquals(-1, result);​

   userAccount = "dogYupi";​
   checkPassword = "12345678";​
   result = userService.userRegister(userAccount, userPassword, checkPassword);​
   Assertions.assertEquals(-1, result);​

   userAccount = "yupi";​
   result = userService.userRegister(userAccount, userPassword, checkPassword);​
   Assertions.assertTrue(result > 0);​
}

执行 报错了【电脑在 idea 更新了一些配置后这里不会报错了,依旧报错按照下面更换正则表达式】

image.png

  • Java 过滤特殊字符的正则表达式换成 [`~!@#$%^&()+=|{}':;',\[\].<>/?~!@#¥%……&()——+|{}【】‘;:”“’。,、?] 或者 [^a-zA-Z0-9] (如果不行,搜索合适的正则表达式),再次执行,报错了(是因为数据库中没有dogYupi 这个账户,设置与其返回值为 -1,所以报错)

image.png

image.png

  • 再次执行即可

image.png

image.png