数据库设计
1.什么是数据库?存数据的
2.数据库里有什么?数据表(理解为excel表格)
3.java操作数据库,代替人工
4.什么是设计数据库表?
5.有哪些表(模型)?表中有哪些字段?字段的类型?数据库字段添加索引?
6.表与表之间的关联
7.性别是否需要加索引?
用户表
字段 | 说明 | 类型 |
---|---|---|
id | 主键 | bigint |
userName | 昵称 | varchar |
userAccount | 登录账号 | varchar |
avatarUrl | 头像 | varchar |
gender | 性别 | tinyint |
userPassword | 密码 | varchar |
phone | 电话 | varchar |
邮箱 | varchar | |
userStatus | 用户状态 | int |
createTime | 创建时间 | datetime |
updateTime | 更新时间 | datetime |
isDelete | 是否删除(逻辑删除) | tinyint |
userRole | 用户角色 0-普通用户 1-管理员 | int |
… |
isValid
和isDelete
是否重复呢?
前者是与业务有关系的,比如是否已经通过验证、是否被管理员封号、是否可以正常使用系统,后者这个字段和业务是没有任何关系的,表示逻辑删除
createTime
、updateTime
、isDelete
基本是所有数据库设计中都要有的,对于数据管理、审计跟踪、逻辑删除这些操作的至关重要
要不要给这个字段索引?
是否要加,取决于是否要根据这个字段搜素信息
性别是否要加索引?
一般都不需要
- 基数小,种类不多,区分度太小
- 查询模式,很少基于性别单独进行
建表
新版IDEA建表时,不同页面
完整SQL语句
create table user
(
id bigint auto_increment primary key,
username varchar(256) null comment '用户昵称',
userAccount varchar(256) null comment '账号',
avatarUrl varchar(1024) null comment '用户头像',
gender tinyint null comment '性别',
userPassword varchar(512) not null comment '密码',
email varchar(512) null comment '邮箱',
userStatus int default 0 null comment '状态 0-正常',
phone varchar(128) null comment '电话',
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 '是否删除'
)
comment '用户表';
登录/注册
推荐先做后端,因为更好思考逻辑,理清逻辑后更好写前端
后端
一、规整项目目录
新建包(目录) controller、service、utils
一些目录文件说明
| 目录/文件
| 说明
|
| — | — |
| | 就是请求层或者叫控制层。然后这个目录里的所有的文件专门用来接收请求,不做任何的业务处理,只去接收请求
|
| | 专门用来编写业务逻辑,那比如说登录注册这些就是业务逻辑
|
| | 一个数据访问层,就是这一层的文件,就是专门用于从数据库中去查询数据,去取数据、增删改查之类的
|
| | 定义了数据库的一些和数据库相对应的模型,或者用到的一些封装类
|
| | 存放一些东西,比如说加密、格式转换、日期转换等等。(就是和我们业务关系不太大的,为了节省我们的操作)
|
| | 一般写前后端不分离的项目,在static放一些静态文件(没用删掉)
|
| | 一般写前后端不分离的项目,放页面模板文件(没用删掉) |
二、实现基本数据库操作
自动生成器的使用
MyBatisX 插件,自动根据数据库生成 domain 实体对象、mapper(操作数据库的对象)、mapper.xml(定义了 mapper对象和数据库的关联,可以在里面自己写 SQL)、service(包含常用的增删改查)、serviceImpl(具体实现 service)
(1) 模型 user 对象自动生成
(2) 测试一下
这里可以Alt + Enter user 使用下面这个插件,即可自动生成set 相关方法,再自己随便设置参数即可
进行测试时会报如下错误
mybatis-plus默认会将驼峰转换成下划线,所以就出现 在“字段列表”中出现未知列“user_account”,在application.yml关闭默认转换
在文件中添加如下内容
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
再次运行即可
三、注册逻辑
- 用户在前端输入账户和密码、以及校验码
- 校验用户的账户、密码、校验密码是否符合要求
- 非空
- 账户不小于 4 位
- 密码不小于 8 位
- 账户不能重复
- 账户不包含特殊字符
- 校验密码和密码相同
- 对密码进行加密(密码不能直接明文存储到数据库中)
- 向数据库插入用户数据
UserService
/**
* 用户注册
* @param userAccount 用户账户
* @param userPassword 用户密码
* @param checkPassword 校验密码
* @return 新用户id
*/
long userRegister(String userAccount, String userPassword, String checkPassword);
UserServiceImpl
@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)){
// TODO
return -1;
}
if(userAccount.length()<4){
return -1;
}
if(userPassword.length()<8||checkPassword.length()<8){
return -1;
}
//账户不能包含特殊字符
String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\\\\\[\\\\\\\\].<>/?
~!@#¥%……&*()——+|{}【】‘;:”“’。,、?\\s]";
Matcher matcher= Pattern.compile(validPattern).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();
}
}
引入依赖,这是一个工具类库
在 Maven 中央仓库 搜索 Apache Commons Lang,我们选择了 3.12.0 版本
<!-- 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.校验
if(userAccount==null||userPassword==null||checkPassword==null){
}
// 导入了工具类上面的代码就可以换成下面的
//1.校验
if(StringUtils.isAnyBlank(userAccount,userPassword,checkPassword)){
}
四、测试
@Test
void userRegister() {
// a. 非空
String userAccount = "yupi";
String userPassword = "";
String checkPassword = "12345678";
long result = userService.userRegister(userAccount,userPassword,checkPassword);
Assertions.assertEquals(-1, result);
// b. 账户不小于 4 位
userAccount = "yu";
userPassword = "12345678";
result = userService.userRegister(userAccount,userPassword,checkPassword);
Assertions.assertEquals(-1, result);
// c. 密码不小于 8 位
userAccount = "yupi";
userPassword = "123";
result = userService.userRegister(userAccount,userPassword,checkPassword);
Assertions.assertEquals(-1, result);
// d. 账户不能重复
userAccount = "123456";
userPassword = "12345678";
result = userService.userRegister(userAccount,userPassword,checkPassword);
Assertions.assertEquals(-1, result);
// e. 账户不包含特殊字符
userAccount = "yu pi";
result = userService.userRegister(userAccount,userPassword,checkPassword);
Assertions.assertEquals(-1, result);
// f. 校验密码和密码相同
userAccount = "yupi";
userPassword = "12345678";
checkPassword = "12345678";
result = userService.userRegister(userAccount,userPassword,checkPassword);
Assertions.assertTrue(result > 0);
}