用户中心项目注册功能
参考笔记
https://uold3d6685.feishu.cn/wiki/IOTZwd7g0iS7NOkHCIHcp0q4n8S
✔数据库表设计
- 什么是数据库? 存数据的
- 数据库里有什么? 数据表(理解为 excel 表格)
- Java 操作数据库,代替人工
- 什么是设计数据库表?
- 有哪些表(模型)?表中有哪些字段?字段的类型?数据库字段添加索引?表与表之间的关联?
性别是否需要索引? 不需要,区分度不高的字段。只有2种取值的字段,建了索引数据库也不一定会用,只会白白增加索引维护的额外开销,因为索引也是需要存储的,所以插入和更新的写入操作,同时需要插入和更新你这个字段的索引的。所以说,唯一性太差的字段不需要创建索引,即便用于where条件
- 删除测试 Mybatis-plus 是否引入成功时创建的 user 表,执行如下语句
DROP TABLE IF EXISTS `user
- 建表,执行如下建表语句(或者使用 idea、可视化工具建表)
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='用户表';
规整项目目录
- 新建 controller、service、utils 包,删除测试 Mybatis-plus 是否引入成功时创建的 User、UserMapper、SampleTest
一般SpringBoot项目都是比较固定的,每个层干什么都有规范
✔注册功能
后端-代码生成器的使用
Mybatis-X插件,自动根据数据库生成
- domain(实体对象)
- mapper(操作数据库的对象)
- mapper.xml(定义了mapper对象和数据库的关联,可以在里面自己写SQL)
- service(包含常用的增删改查)
- serviceImpl(具体实现service)
1. 插件的安装
File -> Settings -> Plugins -> 搜索MyBatisX -> Install
2. 插件的使用
勾选 Comment 可以在生成的实体类添加注释 勾选 Actual Column 可以让生成实体类的字段名和数据库保持一致
3. 代码整合
- domain 放入 model 包
- UserMapper 放入mapper 包
- impl 和 UserService 放入 service 包
- 删除 generator
4. 测试
- 鼠标放在 UserService.java 文件的 UserService 上,按住 alt + enter ,选择创建测试类
编写测试代码【安装插件 CenerateAllSetter ,可快速生成代码】
- 增加下述代码
- 增加下述代码
修改生成的代码(删除带有默认值的字段,剩下的字段增加数据) 设置返回值类型
增加代码
完整代码:
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
}
- 执行测试,会发现报错
这里还有一个问题就是生成的代码复制的时候一定要重构项目,否则包名不对,后面就会报错
5. 问题解决
- 问题原因:MyBatisX自动开启从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射
- 问题解决:yml 文件中添加如下配置 官网描述【链接已更新】
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
- 再次测试
TIP
到这里我们的测试就是成功了,后面我们就要自己写代码了
详细设计
- 用户在前端输入账户和密码、以及校验码(todo)
- 校验用户的账户、密码、校验密码是否符合要求
- 账户不小于 4 位(自己扩展校验)
- 密码不小于 8 位
- 账户不能重复
- 账户不包含特殊字符
- 密码和校验密码相同
- 对密码进行加密(千万不能明文存储到数据库中)
- 向数据库插入用户数据
后端-接口测试开发
TIP
如何快速生成注释 在方法上打出 /** 回车即可
src/main/java/com/yupi/usercenter/service/UserService.java 编写 userRegister 方法并实现
去 maven 仓库 引入 commons-lang3 依赖【记得刷新依赖】
这个库里面有检验的方法,这样就可以不用自己写了,自己写太麻烦了 StringUtils.isAnyBlank 用来判断多个字段是不是为空
<!-- 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>
- UserServiceImpl 实现代码
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 中编写测试,执行(加密成功)
后端-单元测试
- ServiceTest 测试代码生成与编写
@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 更新了一些配置后这里不会报错了,依旧报错按照下面更换正则表达式】
- Java 过滤特殊字符的正则表达式换成 [`~!@#$%^&()+=|{}':;',\[\].<>/?~!@#¥%……&()——+|{}【】‘;:”“’。,、?] 或者 [^a-zA-Z0-9] (如果不行,搜索合适的正则表达式),再次执行,报错了(是因为数据库中没有dogYupi 这个账户,设置与其返回值为 -1,所以报错)
- 再次执行即可