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

黑马点评学习笔记02(Mabatis—plus)

前言

首先登陆界面首先还是基于session实现(我当时也很惊讶,怎么用这个😯,结果看了目录,后面就用Redis和Jwt令牌)可能就是一个过渡吧,先用Session实现一遍,然后才能突出后面的很厉害。其实里面还是有很多小知识点的(Mybatis-plus)很值得学习,这个Session实现就当小配角,陪跑🤪我们学。

先来看看登陆界面的代码实现:

UserController类 :

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate IUserService userService;/*** 发送手机验证码*/@PostMapping("code")public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {// TODO 发送短信验证码并保存验证码return userService.sendCode(phone, session);}/*** 登录功能* @param loginForm 登录参数,包含手机号、验证码;或者手机号、密码*/@PostMapping("/login")public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){// TODO 实现登录功能return userService.login(loginForm, session);}

IUserService 接口:

package com.hmdp.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.hmdp.dto.LoginFormDTO;
import com.hmdp.dto.Result;
import com.hmdp.entity.User;import javax.servlet.http.HttpSession;/*** <p>*  服务类* </p>** @author 虎哥* @since 2021-12-22*/
public interface IUserService extends IService<User> {Result sendCode(String phone, HttpSession session);Result login(LoginFormDTO loginForm, HttpSession session);}

IUserService 接口实现类:

package com.hmdp.service.impl;import.../*** <p>* 服务实现类* </p>** @author 虎哥* @since 2021-12-22*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//3.符合,生成验证码String code = RandomUtil.randomNumbers(6);//4.保存验证码到sessionsession.setAttribute("code", code);//5.发送验证码System.out.println("发送短信验证码成功,验证码:" + code);//5.返回okreturn Result.ok();}@Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.校验手机号String phone = loginForm.getPhone();if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//2.校验验证码 不一致直接报错 从session中获取Object cachecode = session.getAttribute("code");String code = loginForm.getCode();if (cachecode == null || !cachecode.toString().equals(code)) {return Result.fail("验证码错误!");}//3.一致,根据手机号查询用户 select * from tb_user where phone = ?User user = query().eq("phone", phone).one();//4.判断用户是否存在if (user == null) {//5.不存在,创建新用户user = createUserWithPhone(phone);}//6.存在,保存用户信息到sessionsession.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));return Result.ok();}private User createUserWithPhone(String phone) {//1.创建用户User user = new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));//2.保存用户save(user);return user;}}

就是很常见的基于session存储来实现的登陆界面,以及Interceptor拦截器,很简单,之前写苍穹外卖的时候都写过了,所以只总结一些新的东西。

我们在保存用户信息和查找用户验证码的时候,并没有像之前一样新建一个Mapper类用SQL语句查找,只是用到了save方法和query方法,这就用到了Mybatis-plus

🌟 MyBatis-Plus 是什么?

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

官方文档: https://baomidou.com

🙌登陆界面这里主要用到了MyBatis Plus的Service查询

通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行、remove删除、list 查询集合、page查询分页

使用步骤:

搭建项目:

  1. 引入依赖:
<!--mybatis plus场景--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency>
  1. 启动类
package com.hmdp;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@MapperScan("com.hmdp.mapper")
@SpringBootApplication
public class HmDianPingApplication {public static void main(String[] args) {SpringApplication.run(HmDianPingApplication.class, args);}}
  1. application.yml
server:port: 8081
spring:application:name: hmdpdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/hmdp?useSSL=false&serverTimezone=UTCusername: rootpassword: 1234redis:host: localhostport: 6379
#    password: 123456lettuce:pool:max-active: 10max-idle: 10min-idle: 1time-between-eviction-runs: 10sjackson:default-property-inclusion: non_null # JSON处理时忽略非空字段
mybatis-plus:type-aliases-package: com.hmdp.entity # 别名扫描包
logging:level:com.hmdp: debug
  1. 定义一个UserService接口继承与MyBatisPlus提供的IService接口:
在这里插入代码片package com.hmdp.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.hmdp.dto.LoginFormDTO;
import com.hmdp.dto.Result;
import com.hmdp.entity.User;import javax.servlet.http.HttpSession;/*** <p>*  服务类* </p>** @author 虎哥* @since 2021-12-22*/
public interface IUserService extends IService<User> {Result sendCode(String phone, HttpSession session);Result login(LoginFormDTO loginForm, HttpSession session);
}
  1. 定义一个UserService的实现类,并且继承与MyBatisPlus提供的ServiceImpl:
package com.hmdp.service.impl;
import.../*** <p>* 服务实现类* </p>** @author 虎哥* @since 2021-12-22*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//3.符合,生成验证码String code = RandomUtil.randomNumbers(6);//4.保存验证码到session
//        session.setAttribute("code", code);//4.保存验证码到redisstringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);//5.发送验证码System.out.println("发送短信验证码成功,验证码:" + code);//5.返回okreturn Result.ok();}@Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.校验手机号String phone = loginForm.getPhone();if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//2.校验验证码 不一致直接报错 从session中获取
//        Object cachecode = session.getAttribute("code");
//        String code = loginForm.getCode();
//        if (cachecode == null || !cachecode.toString().equals(code)) {
//            return Result.fail("验证码错误!");
//        }//2.校验验证码 从redis中获取  不一致直接报错String cachecode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);String code = loginForm.getCode();if (cachecode == null || !cachecode.toString().equals(code)) {return Result.fail("验证码错误!");}//3.一致,根据手机号查询用户 select * from tb_user where phone = ?User user = query().eq("phone", phone).one();//4.判断用户是否存在if (user == null) {//5.不存在,创建新用户user = createUserWithPhone(phone);}//6.存在,保存用户信息到session
//        session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));//6.存在,保存用户信息到redis//6.1 随机生成token,作为登录令牌String token = UUID.randomUUID().toString(true);//6.2 将用户对象转为hash存储UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);Map<String, Object> userMap = BeanUtil.beanToMap(userDTO,new HashMap<>(),CopyOptions.create().setIgnoreNullValue( true).setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString()));//6.3 存储String tokenkey = LOGIN_USER_KEY + token;stringRedisTemplate.opsForHash().putAll( tokenkey, userMap);//6.4设置token有效期stringRedisTemplate.expire( tokenkey, LOGIN_USER_TTL, TimeUnit.MINUTES);//6.4返回tokenreturn Result.ok(token);}private User createUserWithPhone(String phone) {//1.创建用户User user = new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));//2.保存用户save(user);return user;}}

把数据库代码提取出来

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {public Result login(LoginFormDTO loginForm, HttpSession session) {...User user = query().eq("phone", phone).one(); // ← 这里调用了 query()save(user); // ← 这里调用了 save()}private User createUserWithPhone(String phone) {User user = new User();user.setPhone(phone);user.setNickName("user_" + RandomUtil.randomString(10));save(user); // ← 保存用户return user;}
}

📚 一、save() 方法

来源:ServiceImpl 类

public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {@Autowiredprotected M baseMapper; // 自动注入你的 UserMapper@Overridepublic boolean save(T entity) {return baseMapper.insert(entity) == 1; // 调用 BaseMapper 的 insert 方法}
}

所以:

save(user);

实际上就是

this.baseMapper.insert(user); // 通过 UserMapper 执行 SQL 插入
    save(user)↓
ServiceImpl.save(user)↓
baseMapper.insert(user)  ←← 这才是真正的数据库操作↓
UserMapper.insert(user)  (由 MyBatis 执行 SQL

🔍 三、query().eq(“phone”, phone).one() 又是怎么回事?

这是一套 链式编程 API,也是 MyBatis-Plus 的高级功能。

query().eq("phone", phone).one();

等价于

new LambdaQueryChainWrapper<User>(baseMapper).eq(User::getPhone, phone).one();

它做了什么?

  • query() → 创建一个查询构造器(内部使用 baseMapper)
  • .eq(“phone”, phone) → 添加条件:phone = ?
  • .one() → 执行查询,返回一条记录(相当于 SELECT * FROM tb_user WHERE phone = ? LIMIT 1)
query().eq("phone", phone).one()↓
new LambdaQueryChainWrapper<>(baseMapper)↓
wrapper.eq("phone", phone)↓
wrapper.one() → baseMapper.selectOne(wrapper)↓
执行 SQLSELECT * FROM tb_user WHERE phone = ? LIMIT 1

小白啊!!!写的不好轻喷啊🤯如果觉得写的不好,点个赞吧🤪(批评是我写作的动力)

…。。。。。。。。。。。…请添加图片描述

…。。。。。。。。。。。…

http://www.dtcms.com/a/490773.html

相关文章:

  • 晶体管的定义,晶体管测量参数和参数测量仪器
  • 网站建设需要报告2345网址导航app
  • Java 设计模式——工厂模式:从原理到实战的系统指南
  • VTK实战:vtkSurfaceReconstructionFilter——从点云到三维表面的重建利器
  • 基于微信小程序的篮球场馆预订系统【2026最新】
  • java基础 之 Hash家族_哈希冲突
  • 算法--双指针二
  • RK3576开发板/核心板应用分享之开源鸿蒙
  • 公司网站页脚外包公司的业务员
  • [crackme]028-ArturDents-CrackMe#3
  • 黑盒测试与白盒测试
  • 为安防装上“智慧大脑”:解密视频融合平台EasyCVR的智能分析技术内核
  • 同一设备多账号登录,如何避免消息推送“串门”?
  • 【Linux】认识Framebuffer
  • 深圳做网站公司有哪些公司英文购物网站模板下载
  • 力扣热题100道之560和位K的子数组
  • Pixel-Perfect Depth with Semantics-Prompted Diffusion Transformers,nips 2025
  • 网站可以换主机吗做外贸网站 用国外空间 还是 国内空间 区别
  • **SLAM技术:探索现代定位与地图构建的新纪元**在现代科技领域,同步定位与地图构建(SLAM)技术已成为机器人导航和自动驾驶等领
  • 环保教育展厅建设方案-VR垃圾分类体验游戏-垃圾分类拍拍乐
  • 网站空间怎么更换莱芜在线论坛最新消息
  • 龙岩做网站哪家好如何绑定网站域名
  • [Linux系统编程——Lesson14.基础IO:系统文件IO]
  • golang的一些技巧
  • 高性能 Go 语言带 TTL 的内存缓存实现:精确过期、自动刷新、并发安全
  • ML.NET机器学习框架基本流程介绍
  • Day32_【 NLP _2.RNN及其变体 _(2) LSTM】
  • 重庆建站模板代理怎么做p2p网站
  • iis配置网站是什么网站建设方案书阿里云模板
  • 【计算机视觉】SAM 3 技术深潜:从“分割万物”到“理解概念”的范式转移