当前位置: 首页 > news >正文

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.xdnf.cn/news/915895.html

相关文章:

  • 华为OD机试真题——数字螺旋矩阵(2025B卷:100分)Java/python/JavaScript/C++最佳实现
  • aws(学习笔记第四十三课) s3_sns_sqs_lambda_chain
  • 【STM32F1标准库】理论——定时器中的输出比较
  • 桑荫不徙 · 时之沙 | 在筛选与共生之间,向轻盈之境远航
  • C++组合
  • C++.OpenGL (12/64)光照贴图(Lightmaps)
  • 【飞腾AI加固服务器】全国产化飞腾+昇腾310+PCIe Switch的AI大模型服务器解决方案
  • SQL Server 日期时间类型全解析:从精确存储到灵活转换
  • 限流算法java实现
  • 使用 Redisson 实现分布式锁—解决方案详解
  • Gradle 7.0 及以上版本集中管理项目依赖项的版本号、插件版本和库坐标
  • 【Fiddler工具判断前后端Bug】
  • Modbus RTU/TCP 协议详解与Spring Boot集成指南
  • 开疆智能Ethernet/IP转Modbus网关连接西门子BW500积算仪配置案例
  • 【软件工具】批量OCR指定区域图片自动识别内容重命名软件使用教程及注意事项
  • 一个完整的日志收集方案:Elasticsearch + Logstash + Kibana+Filebeat (二)
  • 【Java微服务组件】分布式协调P4-一文打通Redisson:从API实战到分布式锁核心源码剖析
  • WPF八大法则:告别模态窗口卡顿
  • 为什么React列表项需要key?(React key)(稳定的唯一标识key有助于React虚拟DOM优化重绘大型列表)
  • 探索C++标准模板库(STL):String接口的底层实现(下篇)
  • 项目-- Json-Rpc框架
  • 前端模块化
  • 飞牛云一键设置动态域名+ipv6内网直通访问内网的ssh服务-家庭云计算专家
  • 微前端 - Module Federation使用完整示例
  • 《经济学原理》第9版第6章供给、需求和政府政策
  • XSS(跨站脚本攻击)详解
  • linux 用户态时间性能优化工具perf/strace/gdb/varlind/gprof
  • jvm 垃圾收集算法 详解
  • UDP 与 TCP 调用接口的差异:面试高频问题解析与实战总结
  • html如何在一张图片上的某一个区域做到点击事件