【基于SprintBoot+Mybatis+Mysql】电脑商城项目之修改密码和个人资料
🧸安清h:个人主页
🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】
🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。
目录
🎃1.修改密码 -持久层
✨1.1规划需要执行的SQL语句
✨1.2设计接口和抽象方法
✨1.3SQL的映射
✨1.4单元测试
🎃2.修改密码-业务层
✨2.1规划异常
✨2.2设计接口和抽象方法
🎃3.修改密码-控制层
✨3.1处理异常
✨3.2设计请求
✨3.3处理请求
🎃4.修改密码-前端页面
🚀1.个人资料-持久层
✨1.1规划需要执行的SQL语句
✨1.2接口与抽象方法的设计
✨1.3抽象方法的映射
✨1.4 完成功能测试
🚀2.个人资料-业务层
✨2.1规划异常
✨2.2接口和抽象方法
✨2.3实现抽象方法
✨2.4在测试类中测试
🚀3.个人资料-控制层
✨3.1处理异常
✨3.2设计请求
✨3.3处理请求
🚀4.个人资料-前端页面
需要用户提交原始密码和新密码,再根据当前登录的用户进行信息的修改操作。
🎃1.修改密码 -持久层
✨1.1规划需要执行的SQL语句
1.根据用户的uid修改用户password值
update t_user set password=?,modified_user=?,modified_time=? where uid=?
2. 根据uid查询用户的数据。在修改密码之前,首先要保证当前用户的数据存在,检测是否被标记为已经删除、检测输入的原始密码是否正确。
select * from t_user where uid=?
✨1.2设计接口和抽象方法
UserMapper接口,将以上的两个方法的抽象定义出来。将来映射到SQL语句上。
// 根据用户的uid来修改用户密码
// @param uid 用户的id
// @return 返回值为受影响的行数Integer updatePasswordByUid(Integer uid,String password, //用户输入的新密码String modifiedUser, //修改的执行者Date modifiedTime); //修改数据的时间// 根据用户的uid来查询用户的数据
// @param uid 用户的id
// @return 如果找到则返回对象,反之则返回null值User findByUid(Integer uid);
✨1.3SQL的映射
配置到映射文件中 UserMapper.xml文件中:
<update id="updatePasswordByUid">update t_user set password=#{password},modified_user=#{modifiedUser},modified_time=#{modifiedTime}where uid=#{uid}</update><select id="findByUid" resultMap="UserEntityMap">select * from t_user where uid=#{uid}</select>
✨1.4单元测试
@Testpublic void updatePasswordByUid(){userMapper.updatePasswordByUid(2,"123456","管理员",new Date());}@Testpublic void findByUid(){System.out.println(userMapper.findByUid(6));}
🎃2.修改密码-业务层
✨2.1规划异常
1.用户的源密码错误,is_delete=1,uid找不到,在用户没有发现的异常。
2.update在更新时,有可能产生未知的异常,UpdateException。
//用户在更新数据时产生的未知的异常
public class UpdateException extends ServiceException{public UpdateException() {super();}public UpdateException(String message) {super(message);}public UpdateException(String message, Throwable cause) {super(message, cause);}public UpdateException(Throwable cause) {super(cause);}protected UpdateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}
✨2.2设计接口和抽象方法
1.执行用户修改密码的核心方法。
void changePassword(Integer uid,String username,String oldPassword,String newPassword);
2.在实现类中实现当前的抽象方法
@Overridepublic void changePassword(Integer uid, String username, String oldPassword, String newPassword) {User result = userMapper.findByUid(uid);if(result == null || result.getIsDelete() ==1){throw new UserNotFoundException("用户数据不存在");}
// 原始密码和数据库中的密码进行比较String oldMd5Password = getMD5Password(oldPassword,result.getSalt());if(!result.getPassword().equals(oldMd5Password)){throw new PasswordNotMatchException("密码错误");}// 将新的密码设置到数据库中,将新的密码进行加密再去更新String newMd5Password = getMD5Password(newPassword, result.getSalt());Integer rows = userMapper.updatePasswordByUid(uid,newMd5Password,username,new Date());if(rows != 1){throw new UpdateException("更新时数据产生未知的异常");}}
3. 在单元测试类中编写测试方法
@Testpublic void changePassword(){userService.changePassword(7,"timi","123","321");}
🎃3.修改密码-控制层
✨3.1处理异常
UpdateException需要配置在统一的处理异常方法中。
else if(e instanceof UpdateException){result.setState(5003);result.setMessage("更新数据时产生未知的异常");}
✨3.2设计请求
请求路径:/users/change_password
请求参数:String oldPassword,String newPassword(需要和表单中的name属性值保持一致)
请求类型:POST
响应结果:JsonResult<void>
✨3.3处理请求
@RequestMapping("change_password")public JsonResult<Void> change_password(String oldPassword,String newPassword,HttpSession session){Integer uid = getuidFromSession(session);String username = getUsernameFromSession(session);userService.changePassword(uid,username,oldPassword,newPassword);return new JsonResult<>(OK);}
🎃4.修改密码-前端页面
password.html中添加ajax请求的处理,不在手动编写ajax结构,直接复制,然后微调修改参数。
<script>$("#btn-change-password").click(function (){$.ajax({url:"/users/change_password",type:"POST",data:$("#form-change-password").serialize(),dataType:"JSON",success:function (json){if(json.state==200){alert("修改密码成功");}else{alert("修改密码失败");}},error:function (xhr){alert("修改密码时产生未知的异常"+xhr.message);}});});</script>
🚀1.个人资料-持久层
✨1.1规划需要执行的SQL语句
1.更新用户信息的SQL语句:
update t_user set phone=?,email=?,gender=?,modified_user=?,modified_time=? where uid=?
2.根据用户名来查询用户的数据:
select * from t_user where uid=?
查询用户的数据不需要重复开发
✨1.2接口与抽象方法的设计
更新用户的信息方法的定义。
// 更新用户的数据信息
// @param user
// @return 返回值为收影响的行数Integer updateInfoByUid(User user);
✨1.3抽象方法的映射
在UserMapper.xml文件中进行映射编写。
<update id="updateInfoByUid">update t_user set
-- if表示条件判断标签,test接收的是一个返回值为boolean类型的条件,如果test条件的结果为true则执行if标签内部的语句<if test="phone!=null">phone=#{phone},</if><if test="email!=null">email=#{email},</if><if test="gender!=null">gender=#{gender},</if>modified_user=#{modifiedUser},modified_time=#{modifiedTime}where uid=#{uid}</update>
✨1.4 完成功能测试
@Testpublic void updateInfoByUid(){User user = new User();user.setUid(7);user.setPhone("12345678");user.setEmail("test003@qq.com");user.setGender(1);userMapper.updateInfoByUid(user);}
🚀2.个人资料-业务层
✨2.1规划异常
1.设计两个功能:
- 当打开页面获取用户的信息并且填充到对应的文本框中。
- 检测用户是否点击了修改按钮,如果检测到则执行修改用户信息的操作。
2.打开页面可能找不到用户的数据,点击删除按钮之前需要再次的去检测用户的数据是否存在。
✨2.2接口和抽象方法
在service包下的IUService编写以下代码:
// 根据用户的id查询用户的数据
// @param uid 用户id
// @return 用户的数据User getByUid(Integer uid);// 更新用户的数据操作
// @param uid 用户的id
// @param username 用户名
// @param user 用户对象的数据void changeInfo(Integer uid,String username,User user);
✨2.3实现抽象方法
在UserServiceImpl类中添加两个抽象方法的具体实现。
@Overridepublic User getByUid(Integer uid) {User result = userMapper.findByUid(uid);if(result == null || result.getIsDelete() == 1){throw new UserNotFoundException("用户数据不存在");}User user = new User();user.setUsername(result.getUsername());user.setPhone(result.getPhone());user.setEmail(result.getEmail());user.setGender(result.getGender());return user;}// user对象中的数据phone/email/gender,手动再将uid/username封装到user对象中@Overridepublic void changeInfo(Integer uid, String username, User user) {User result = userMapper.findByUid(uid);if(result == null || result.getIsDelete() == 1){throw new UserNotFoundException("用户数据不存在");}user.setUid(uid);user.setModifiedUser(username);user.setModifiedTime(new Date());Integer rows = userMapper.updateInfoByUid(user);if(rows != 1){throw new UpdateException("更新时数据产生未知的异常");}}
✨2.4在测试类中测试
@Testpublic void getByUid(){System.out.println(userService.getByUid(7));}@Testpublic void changeInfo(){User user=new User();user.setPhone("87654321");user.setEmail("666333@qq.com");user.setGender(0);userService.changeInfo(7,"timi",user);}
🚀3.个人资料-控制层
✨3.1处理异常
暂无。
✨3.2设计请求
1.设置-打开页面就发送当前用户数据的查询。即在打开页面的时候,页面就显示username,phone,email等信息。
请求路径:/users/get_by_uid
请求参数:HttpSession session
请求类型:GET
响应结果:JsonResult<User>
2.点击修改按钮发送用户的数据修改操作请求的设计。
请求路径:/users/change_info
请求参数:User user,HttpSession session
请求类型:POST
响应结果:JsonResult<Void>
✨3.3处理请求
@RequestMapping("get_by_uid")public JsonResult<User> getByUid(HttpSession session){User data = userService.getByUid(getuidFromSession(session));return new JsonResult<>(OK,data);}@RequestMapping("change_info")public JsonResult<Void> changeInfo(User user,HttpSession session){
// user对象有四部分数据:username,phone,email,gender
// uid数据需要再次封装到user对象中Integer uid = getuidFromSession(session);String username = getUsernameFromSession(session);userService.changeInfo(uid,username,user);return new JsonResult<>(OK);}
}
🚀4.个人资料-前端页面
1.在打开userdata.html页面自动发送ajax请求(get_by_uid),查询到的数据填充到页面上。
<!-- 一旦检测到当前的页面被加载就会触发ready方法-->// $(document).ready(function (){//// })$(document).ready(function (){$.ajax({url:"/users/get_by_uid",type:"GET",data:$("#form-change-info").serialize(),dataType:"JSON",success:function (json){if(json.state==200){// 将查询的数据重新设置到控件中$("#username").val(json.data.username)$("#phone").val(json.data.phone)$("#email").val(json.data.email)let radio = json.data.gender == 0 ? $("#gender-female") : $("#gender-male");// prop()表示给某个元素添加属性及属性的值radio.prop("checked","checked")}else{alert("用户的数据不存在");}},error:function (xhr){alert("查询用户时产生未知的异常"+xhr.message);}});})
2.在检测到用户点击了修改按钮之后也需要发送一个ajax请求(change_info)。
<script>$("#btn-change-info").click(function (){$.ajax({url:"/users/change_info",type:"POST",data:$("#form-change-info").serialize(),dataType:"JSON",success:function (json){if(json.state==200){alert("用户信息修改成功");// 修改成功后重新加载当前的页面location.href="userdata.html"}else{alert("用户信息修改失败");}},error:function (xhr){alert("用户信息修改时产生未知的异常"+xhr.message);}});});
相关文章:

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之修改密码和个人资料
🧸安清h:个人主页 🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🎃1.修改密码 -持久…...

十一、CentOS Stream 9 安装 Docker
一、Docker 环境安装 1、软件源(仓库)信息 使用如下命令可列出当前系统配置的所有软件源(仓库)信息 # 列出所有软件源 dnf repolist 这表明系统有三个仓库 AppStream 、 BaseOS、Extras-Common 被启用 2、配置软件源镜像 使用如下命令可配置 Docker 软件包下载的镜像地址 …...

FreeRTOS学习 --- 中断管理
什么是中断? 让CPU打断正常运行的程序,转而去处理紧急的事件(程序),就叫中断 中断执行机制,可简单概括为三步: 1,中断请求 外设产生中断请求(GPIO外部中断、定时器中断…...

如何在Intellij IDEA中识别一个文件夹下的多个Maven module?
目录 问题描述 理想情况 手动添加Module,配置Intellij IDEA的Project Structure 问题描述 一个文件夹下有多个Maven项目,一个一个开窗口打开可行但是太麻烦。直接open整个文件夹会发现Intellij IDEA默认可能就识别一个或者几个Maven项目,如…...
机器学习模型--线性回归、逻辑回归、分类
一、线性回归 级别1:简单一元线性回归(手工实现) import numpy as np import matplotlib.pyplot as plt# 生成数据 X np.array([1, 2, 3, 4, 5]) y np.array([2, 4, 5, 4, 5])# 手动实现梯度下降 def gradient_descent(X, y, lr0.01, epo…...
gitlab个别服务无法启动可能原因
目录 一、gitlab的puma服务一直重启 1. 查看日志 2. 检查配置文件 3. 重新配置和重启 GitLab 4. 检查系统资源 5. 检查依赖和服务状态 6. 清理和优化 7. 升级 GitLab 8. 查看社区和文档 二、 gitlab个别服务无法启动可能原因 1.服务器内存或磁盘已满 2.puma端口冲突…...
react的antd表格数据回显在form表单中
1、首先为table添加编辑按钮 {title: 操作,align: center,render: (_: any, record: any) > (<div style{{ display: flex, alignItems: center, justifyContent: space-evenly }}><Buttonsize"small"onClick{() > deitor(record)} style{{ margin…...
深度分析:网站快速收录与网站内容多样性的关系
本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/87.html 网站快速收录与网站内容多样性之间存在着密切的关系。以下是对这一关系的深度分析: 一、网站内容多样性对快速收录的影响 提升搜索引擎抓取效率: 多样化的…...

feign 远程调用详解
在平常的开发工作中,我们经常需要跟其他系统交互,比如调用用户系统的用户信息接口、调用支付系统的支付接口等。那么,我们应该通过什么方式进行系统之间的交互呢?今天,简单来总结下 feign 的用法。 1:引入依…...

【Android】jni开发之导入opencv和libyuv来进行图像处理
做视频图像处理时需要对其进行水印的添加,放在应用层调用工具性能方面不太满意,于是当下采用opencvlibyuv方法进行处理。 对于Android的jni开发不是很懂,我的需求是导入opencv方便在cpp中调用,但目前找到的教程都是把opencv作为模…...

【Elasticsearch】terms聚合误差问题
Elasticsearch中的聚合查询在某些情况下确实可能存在误差,尤其是在处理分布式数据和大量唯一值时。这种误差主要来源于以下几个方面: 1.分片数据的局部性 Elasticsearch的索引通常被分成多个分片,每个分片独立地计算聚合结果。由于数据在分…...
深入理解 `box-sizing: border-box;`:CSS 布局的利器
深入理解 box-sizing: border-box;:CSS 布局的利器 默认行为示例代码 使用 box-sizing: border-box;示例代码 全局应用 box-sizing: border-box;示例代码 实际应用场景1. 表单布局2. 网格布局 总结 在 CSS 中,box-sizing 属性决定了元素的总宽度和高度是…...
【原子工具】快速幂 快速乘
题幂算.一切即1 阴阳迭变积微著,叠浪层峦瞬息功 莫道浮生千万事,元知万象一归宗 文章目录 快速幂原始快速幂(O(logn))二分递归形式非递归形式 模下意义的快速幂(O(logn))二分递归形式非递归形式 快速乘龟速…...

Apache SeaTunnel 整体架构运行原理
概述 SeaTunnel 缘起 数据集成在现代企业的数据治理和决策支持中扮演着至关重要的角色。随着数据源的多样化和数据量的迅速增长及业务需求的快速变化,企业需要具备强大的数据集成能力来高效地处理数据。SeaTunnel通过其高度可扩展和灵活的架构,帮助企业…...
Nginx如何实现 TCP和UDP代理?
文章目录 前言 Nginx之TCP和UDP代理 工作原理示意图 配置文件和命令参数注释 基本命令 配置实例说明 TCP代理实例UDP代理实例 总结 前言 Nginx是一个高性能的HTTP和反向代理服务器,同时也支持TCP/UDP代理。在1.9.13版本后,Nginx已经支持端口转发&…...

蓝桥杯思维训练营(三)
文章目录 题目详解680.验证回文串 II30.魔塔游戏徒步旅行中的补给问题观光景点组合得分问题 题目详解 680.验证回文串 II 680.验证回文串 II 思路分析:这个题目的关键就是,按照正常来判断对应位置是否相等,如果不相等,那么就判…...

开箱即用的.NET MAUI组件库 V-Control 发布了!
之前写过挺多的MAUI Sample,其中有很多代码可以打包成组件,当组件完善到一定程度,我会把控件封装起来放到控件库中。 今天,在这个仓库建立一年零八个月后,我觉得可以考虑将其作为开源库发布。 有很多网友在观望.NET …...

动手学图神经网络(9):利用图神经网络进行节点分类 WeightsBiases
利用图神经网络进行节点分类Weights&Biases 引言 在本篇博客中,将深入探讨如何使用图神经网络(GNNs)来完成节点分类任务。以 Cora 数据集为例,该数据集是一个引用网络,节点代表文档,推断每个文档的类别。同时,使用 Weights & Biases(W&B)来跟踪实验过程和…...
【文件上传、秒传、分片上传、断点续传、重传】
文章目录 获取文件对象文件上传(秒传、分片上传、断点续传、重传)优化 获取文件对象 input标签的onchange方法接收到的参数就是用户上传的所有文件 <html lang"en"><head><title>文件上传</title><style>#inp…...

使用Pygame制作“打砖块”游戏
1. 前言 打砖块(Breakout / Arkanoid) 是一款经典街机游戏,玩家控制一个可左右移动的挡板,接住并反弹球,击碎屏幕上方的砖块。随着砖块被击碎,不仅能获得分数,还可以体验到不断加速或复杂的反弹…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 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 …...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...