hmdp知识点

1. 前置知识

1.1 MyBatisPlus的基本使用

1.1.1 引入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version>
</dependency>

1.1.2 建立实体类和数据库表

实体类:

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_user")
public class User implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 手机号码*/private String phone;/*** 密码,加密存储*/private String password;/*** 昵称,默认是随机字符*/private String nickName;/*** 用户头像*/private String icon = "";/*** 创建时间*/private LocalDateTime createTime;/*** 更新时间*/private LocalDateTime updateTime;}

数据库表:

注解所属框架用途说明
@DataLombok自动生成 getter/setter/toString/equals/hashCode
@EqualsAndHashCode(callSuper = false)Lombok控制 equals 和 hashCode 是否包含父类字段
@Accessors(chain = true)Lombok支持链式调用(set 方法返回 this)
@TableName("tb_user")MyBatis Plus指定当前类对应的数据库表名
@TableId(value = "id", type = IdType.AUTO)MyBatis Plus标明主键字段,并设置数据库主键列名和类型

1.1.3 application.yml

mybatis-plus:type-aliases-package: com.hmdp.entity # 别名扫描包

1.1.4 启动类扫描包

package com.hmdp;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@MapperScan("com.hmdp.mapper") // MyBatis扫描包
@SpringBootApplication
public class HmDianPingApplication {public static void main(String[] args) {SpringApplication.run(HmDianPingApplication.class, args);}
}

1.1.5 Mapper接口

import com.hmdp.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface UserMapper extends BaseMapper<User> {}

BaseMapper 是什么?

BaseMapper<T> 是 MyBatis Plus 提供的一个接口,包含一系列常用的 CRUD 操作方法(增删改查),这些方法已经实现好了,你可以直接使用。

常用方法举例:

方法名功能说明
int insert(User entity)插入一条记录
int deleteById(Serializable id)根据主键删除一条记录
int updateById(User entity)根据主键更新记录
User selectById(Serializable id)根据主键查询记录
List<User> selectList(QueryWrapper<User> wrapper)查询满足条件的多条记录
List<User> selectAll()查询所有记录(需自己定义 SQL 或扩展 Wrapper)

1.1.6 Service接口

package com.hmdp.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.hmdp.entity.User;public interface IUserService extends IService<User> {}

IService 是什么?

IService<T> 是 MyBatis Plus 提供的一个 通用服务接口,封装了常见的 业务层操作方法(CRUD),例如:

方法名功能说明
boolean save(User entity)插入一条记录
boolean removeById(Serializable id)根据主键删除记录
boolean updateById(User entity)根据主键更新记录
User getById(Serializable id)根据主键查询记录
List<User> list()查询所有记录
IPage<User> page(IPage<User> page)分页查询数据
boolean saveOrUpdate(User entity)存在则更新,不存在则插入

1.1.8 ServiceImpl实现类

package com.hmdp.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.entity.User;
import com.hmdp.mapper.UserMapper;
import com.hmdp.service.IUserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {}
UserServiceImpl 是 IUserService 的实现类继承 ServiceImpl,获得通用 CRUD 方法
必须指定两个泛型参数Mapper 和 Entity
使用 @Service 注解让 Spring 管理这个类
可以直接使用通用方法如 save()getById()list() 等
支持扩展自定义方法在接口中声明,在实现类中实现

1.1.9 Controller接口

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate IUserService userService;@Resourceprivate IUserInfoService userInfoService;/*** 发送手机验证码*/@PostMapping("code")public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {// TODO 发送短信验证码并保存验证码return Result.fail("功能未完成");}/*** 登录功能* @param loginForm 登录参数,包含手机号、验证码;或者手机号、密码*/@PostMapping("/login")public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){// TODO 实现登录功能return Result.fail("功能未完成");}/*** 登出功能* @return 无*/@PostMapping("/logout")public Result logout(){// TODO 实现登出功能return Result.fail("功能未完成");}@GetMapping("/me")public Result me(){// TODO 获取当前登录的用户并返回return Result.fail("功能未完成");}@GetMapping("/info/{id}")public Result info(@PathVariable("id") Long userId){// 查询详情UserInfo info = userInfoService.getById(userId);if (info == null) {// 没有详情,应该是第一次查看详情return Result.ok();}info.setCreateTime(null);info.setUpdateTime(null);// 返回return Result.ok(info);}
}

1.2 校验手机号/验证码格式的工具类

注意:要引入hutool依赖。

package com.hmdp.utils;public abstract class RegexPatterns {/*** 手机号正则*/public static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";/*** 邮箱正则*/public static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";/*** 密码正则。4~32位的字母、数字、下划线*/public static final String PASSWORD_REGEX = "^\\w{4,32}$";/*** 验证码正则, 6位数字或字母*/public static final String VERIFY_CODE_REGEX = "^[a-zA-Z\\d]{6}$";}
package com.hmdp.utils;import cn.hutool.core.util.StrUtil;public class RegexUtils {/*** 是否是无效手机格式* @param phone 要校验的手机号* @return true:符合,false:不符合*/public static boolean isPhoneInvalid(String phone){return mismatch(phone, RegexPatterns.PHONE_REGEX);}/*** 是否是无效邮箱格式* @param email 要校验的邮箱* @return true:符合,false:不符合*/public static boolean isEmailInvalid(String email){return mismatch(email, RegexPatterns.EMAIL_REGEX);}/*** 是否是无效验证码格式* @param code 要校验的验证码* @return true:符合,false:不符合*/public static boolean isCodeInvalid(String code){return mismatch(code, RegexPatterns.VERIFY_CODE_REGEX);}// 校验是否不符合正则格式private static boolean mismatch(String str, String regex){if (StrUtil.isBlank(str)) {return true;}return !str.matches(regex);}
}

2. 短信登陆

2.1 基于Session实现登陆

用户第一次访问服务器时,服务器内部会生成一个session,这个session属于这个用户,有一个sessionID,服务器会自动将sessionID传递给浏览器,浏览器会自动保存sessionID,之后浏览器的每一次请求都会自动携带这个sessionID

2.2.1 实现发送短信验证码功能

业务流程:

  1. 前端提交手机号到后端
  2. 后端校验手机号
    1. 手机号格式不符合,返回手机号格式错误
    2. 手机号格式符合,下一步
  3. 生成验证码
  4. 保存验证码到当前用户的session中
  5. 将验证码发送给前端

前端向后端发送请求的俩种方式(POST请求):

  • http://192.168.31.20:8080/api/user/code?phone=17771818987(通过Nginx代理转发)
  • http://localhost:8081/code?phone=17771818987(直接访问后端)

UserController.java

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate IUserService userService;/*** 发送手机验证码*/@PostMapping("code")public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {//  发送短信验证码并保存验证码return userService.sendCode(phone,session);}}

IUserService.java

public interface IUserService extends IService<User> {/*** 登陆发送短信验证码接口* @param phone* @param session* @return*/Result sendCode(String phone, HttpSession session);
}

UserServiceImpl.java

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {/*** 发送短信验证码实现* @param phone* @param session* @return*/@Overridepublic Result sendCode(String phone, HttpSession session) {// 1. 校验手机号if (RegexUtils.isPhoneInvalid(phone)) {// 2. 不符合,返回错误信息return Result.fail("手机号格式错误");}// 3. 符合,设生成验证码String code = RandomUtil.randomNumbers(6);// 通过hutool包,生成6位随机数// 4. 保存验证码到sessionsession.setAttribute("code", code);// 5. 发送验证码给前端log.debug("发送短信验证码成功, 短信验证码是:{}", code);// 返回OKreturn Result.ok();}
}

2.2.2 实现短信验证码登陆和注册

前端参数:

  • 请求方式:POST
  • 请求路径:/user/login
  • 请求参数:phone, code(json数据)
  • 返回值:无

业务流程:

  1. 前端传递phone和code
  2. 通过session对象校验验证码
    1. 验证码错误,返回“验证码错误”
    2. 验证码正确,去数据库根据手机号查询用户
  3. 用户是否存在
    1. 用户不存在,创建新用户,保存新用户的数据库
    2. 用户存在,保存用户信息到session

LoginFormDTO对象:

@Data
public class LoginFormDTO {private String phone;private String code;private String password;
}

2.2.3 实现登陆校验拦截器

业务流程:

  1. 请求并携带cookie
  2. 从session获取用户
  3. 判断用户是否存在session中
    1. 用户存在,表示手机号和验证码已经核验通过
    2. 用户不存在,拦截

2.2 集群的session共享问题

2.3 基于Redis实现共享session登陆

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/84042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分享5个免费5个在线工具网站:Docsmall、UIED Tool在线工具箱、草料二维码、图片在线压缩、表情符号

01. Docsmall 它是一个免费的在线图片与PDF处理工具&#xff0c;功能主要包含Ai图片处理工具&#xff0c;图片压缩工具&#xff0c;图片PDF格式转换工具等&#xff0c;如下图&#xff0c;我认为比较实用的是自动抠图、图片变高清、图片压缩和PDF压缩。 https://docsmall.com/…

打通印染车间“神经末梢”:DeviceNet转Ethernet/IP连接机器人的高效方案

在印染行业自动化升级中&#xff0c;设备联网需求迫切。老旧印染设备多采用Devicenet协议&#xff0c;而新型工业机器人普遍支持Ethernet/IP协议&#xff0c;协议不兼容导致数据交互困难&#xff0c;设备协同效率低、生产监控滞后&#xff0c;成了行业数字化转型的阻碍。本文将…

RSA加密算法:非对称密码学的基石

一、RSA算法概述 RSA&#xff08;Rivest-Shamir-Adleman&#xff09;是1977年由Ron Rivest、Adi Shamir和Leonard Adleman提出的非对称加密算法&#xff0c;它基于大数分解的数学难题&#xff0c;是当今应用最广泛的公钥密码系统。RSA的核心思想是使用一对密钥&#xff08;公钥…

杭州瑞盟 MS35774/MS35774A 低噪声256细分微步进电机驱动,用于空调风门电机驱动,香薰电机驱动

杭州瑞盟 MS35774/MS35774A 低噪声256细分微步进电机驱动&#xff0c;用于空调风门电机驱动&#xff0c;香薰电机驱动 简述 MS35774/MS35774A 是一款高精度、低噪声的两相步进 电机驱动芯片&#xff0c;芯片内置功率 MOSFET &#xff0c;长时间工作的平均电 流可以达到 1…

驶向智能未来:车载 MCP 服务与边缘计算驱动的驾驶数据交互新体验

引言 在人工智能技术与车载算力持续突破的驱动下&#xff0c;现代车辆的数字化进程正加速推进。车联网系统将突破传统云端架构的局限&#xff0c;依托边缘计算与 AI 融合技术&#xff0c;实现人车交互体验的范式重构‌。通过构建基于多源异构数据的自动化分析框架&#xff0c;…

Python数据可视化科技图表绘制系列教程(三)

目录 单一柱状图 分组柱状图 堆积柱状图 百分比柱状图 均值柱状图 不等宽柱状图 有序柱状图 条形图 发散条形图 在条上添加标签的发散条形图 基础棒棒糖图1 基础棒棒糖图2 【声明】&#xff1a;未经版权人书面许可&#xff0c;任何单位或个人不得以任何形式复制、发…

JavaScript 数组与流程控制:从基础操作到实战应用

在 JavaScript 编程的世界里&#xff0c;数组是一种极为重要的数据结构&#xff0c;它就像是一个有序的 “收纳盒”&#xff0c;能够将多个值整齐地存储起来。而流程控制语句则像是 “指挥官”&#xff0c;能够按照特定的逻辑对数组进行遍历和操作。接下来&#xff0c;就让我们…

十(1). 强制类型转换

继第十部分C强制类型转换的四种方式&#xff0c;再进行强化巩固一下知识点 static_cast 最常用的&#xff0c;在指针之间做转换 const_cast 去除常量属性 dynamic_cast 用在基类和派生类之间的转换 reinterpret_cast 在任意类型之间进行转 10.1 static_cast 常见的使用场景&am…

Git版本控制工具详解

如何区分开发环境和生产环境呢 答案就是写不同的配置文件&#xff0c;开发的设置成开发需要的&#xff0c;生产的设置成生产需要的&#xff0c;共同放到config这个配置文件夹下面&#xff0c;开发和生成的时候分别加载不同的配置文件 方式二就是使用相同的一个入口配置文件&a…

反向传播的核心是什么:计算损失函数对可训练参数的梯度=== 损失函数能通过计算图连接到可训练参数

反向传播的核心是什么:计算损失函数对可训练参数的梯度 损失函数能通过计算图连接到可训练参数 在深度学习中,反向传播的核心是计算损失函数对可训练参数的梯度,从而更新这些参数。对于LLM(大型语言模型)而言,是否需要“LLM输出的参数”才能进行反向传播 一、反向传播…

KINGCMS被入侵

现象会强制跳转到 一个异常网站,请掉截图代码. 代码中包含经过混淆处理的JavaScript&#xff0c;它使用了一种技术来隐藏其真实功能。代码中使用了eval函数来执行动态生成的代码&#xff0c;这是一种常见的技术&#xff0c;恶意脚本经常使用它来隐藏其真实目的。 这段脚本会检…

深入探索串的高级操作:从算法到 LeetCode 实战

串是编程中最常用的数据结构之一&#xff0c;从简单的文本处理到复杂的文本匹配算法&#xff0c;串的应用无处不在。在掌握了串的基本概念、存储结构以及KMP算法之后&#xff0c;现在让我们深入探索串的更多高级操作&#xff0c;例如求子串、串的替换等&#xff0c;并通过LeetC…

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …

OneNet + openssl + MTLL

1.OneNet 使用的教程 1.在网络上搜索onenet&#xff0c;注册并且登录账号。 2.产品服务-----物联网服务平台立即体验 3.在底下找到立即体验进去 4.产品开发------创建产品 5.关键是选择MQTT&#xff0c;其他的内容自己填写 6.这里产品以及开发完成&#xff0c;接下来就是添加设…

【Fiddler工具判断前后端Bug】

Fiddler工具判断前后端Bug的方法 使用Fiddler抓包工具可以高效定位问题是出在前端还是后端&#xff0c;主要通过分析请求和响应的内容、状态码、数据格式等关键信息。 分析请求是否成功发送 检查请求是否从客户端正确发出&#xff0c;观察Fiddler抓取的请求列表。若请求未出…

【论文阅读笔记】《A survey on deep learning approaches for text-to-SQL》

文章目录 一、论文基本信息1. 文章标题2. 所属刊物/会议3. 发表年份4. 作者列表5. 发表单位 二、摘要三、解决问题四、创新点五、自己的见解和感想六、研究背景七、研究方法&#xff08;模型、实验数据、评估指标&#xff09;八、总结&#xff08;做了什么、得到了什么、有什么…

【强连通分量 缩点 最长路 拓扑排序】P2656 采蘑菇|普及+

本文涉及知识点 C图论 强连通分量 缩点 最长路 拓扑排序 P2656 采蘑菇 题目描述 小胖和 ZYR 要去 ESQMS 森林采蘑菇。 ESQMS 森林间有 N N N 个小树丛&#xff0c; M M M 条小径&#xff0c;每条小径都是单向的&#xff0c;连接两个小树丛&#xff0c;上面都有一定数量的…

Dubbo Logback 远程调用携带traceid

背景 A项目有调用B项目的服务&#xff0c;A项目使用 logback 且有 MDC 方式做 traceid&#xff0c;调用B项目的时候&#xff0c;traceid 没传递过期&#xff0c;导致有时候不好排查问题和链路追踪 准备工作 因为使用的是 alibaba 的 dubbo 所以需要加入单独的包 <depend…

nodejs:用 nodemailer 发送一封带有附件的邮件

我们将使用 nodemailer 库来发送带有附件的邮件。 首先&#xff0c;确保已经安装了nodemailer。如果没有安装&#xff0c;可以通过 npm install nodemailer 来安装。 cnpm install nodemailer --save dependencies: – nodemailer ^7.0.3 步骤&#xff1a; 引入nodemailer模…

Scade 语言概念 - 方程(equation)

在 Scade 6 程序中自定义算子(Operator)的定义、或数据流定义(data_def)的内容中&#xff0c;包含一种基本的语言结构&#xff1a;方程(equation)(注1)。在本篇中&#xff0c;将叙述 Scade 语言方程的文法形式&#xff0c;以及作用。 注1: 对 Scade 中的 equation, 或 equation…