【 苍穹外卖 | Day2】

1. 相关视频

Day2的全部视频集数

2. 学习记录

2.1 对象属性拷贝

当DTO与实体类或者VO对象之间的一个装换的时候,如果通过new创建对象,然后调用set方法进行属性赋值,不够方便,代码不够简洁。当属性过多时候,代码就会显得臃肿。所以采用对象属性拷贝。推荐使用MapStruct

public void save(EmployeeDTO employee){BeanUtils.copyProperties(employeeDTO,employee);
}

MapStruct 快速指南 | Baeldung中文网


2.2 分页查询

分页查询,项目经常遇到的功能,本人也学过相关的知识,编写过相关的代码,这里也记录一下

对于分页,可以采取MySQL的limit关键字,但是在实际项目的开发,这样写不够代码的简洁以及提高代码量,工作效率低下,因此还是使用框架来进行分页查询的开发

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pagehelper}</version>
</dependency>

( 对于版本的多少,可以去maven的repository复制,这里主要是作于技术的记录 )

这个插件底层是基于mybatis的拦截器,会将我们的sql语句查询进行一个拼接,动态拼接limit的参数,并且基于参数的计算输出结果

这里使用分页查询插件,最终也还是使用到MySQL的语句进行查询,似乎好像还有其他的框架可以不需要写MySQL语句,直接就是调用就可以返回相关的结果,这个大家可以在评论区讨论

前提准备

@Data
public class EmployeePageQueryDTO implements Serializable {//员工姓名private String name;//页码private int page;//每页显示记录数private int pageSize;}/*----------------------------------------------------------------*//*** 封装分页查询结果*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {private long total; //总记录数private List records; //当前页数据集合}

@Service
public class EmployeeServiceImpl implements EmployeeService { /*** 分页查询** @param pageQueryDTO  分页查询参数* @return  分页结果*/@Overridepublic PageResult page(EmployeePageQueryDTO pageQueryDTO) {// 使用pageHelper分页查询PageHelper.startPage(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());// 这里需要进行MySQL语句的查询Page<Employee> page = employeeMapper.page(pageQueryDTO);long total = page.getTotal();List<Employee> records = page.getResult();return new PageResult(total, records);}
}/*--------------------------------------------------------------------*/@Mapper
public interface EmployeeMapper {/*** 分页查询* @param pageQueryDTO  分页查询参数* @return  分页结果*/Page<Employee> page(EmployeePageQueryDTO pageQueryDTO);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.EmployeeMapper"><select id="page" resultType="com.sky.entity.Employee">select * from employee<where><if test="name != null and name != ''">and name like concat('%', #{name}, '%')</if>order by crate_time desc</where></select>
</mapper>

使用like关键字进行一个模糊查询

友情提醒:mapper文件中的SQL语句不要加分号,否则会报错,因为你加分号之后,limit拼接在之后,就不是正确的mysql语句


3. JWT流程 && ThreadLocal

4. 时间格式处理

推荐使用第二种方式,因为第二种方式是一个统一的配置。如果没有进行一个配置的话,那么返回的是一个集合。另外这里的converters是我们Spring MVC中所有的转换器,并且有顺序排列使用,增加的消息转换器是排在最后,那么为了让我们自定义的转换器优先使用,就需要设置权重

注意:是MappingJackson2HttpMessageConverter,不是MappingJackson2CborHttpMessageConverter,没有Cbor

/*** 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]*/
public class JacksonObjectMapper extends ObjectMapper {public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";//public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";public JacksonObjectMapper() {super();//收到未知属性时不报异常this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);//反序列化时,属性不存在的兼容处理this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));//注册功能模块 例如,可以添加自定义序列化器和反序列化器this.registerModule(simpleModule);}
}

5. 完善苍穹外卖 —— 密码修改业务

自己完成苍穹外卖的员工密码修改功能

定义传输数据的DTO对象

一开始,看着接口文档还有一个Integer类型的empId,但是经过我后面调试,以及在前端使用f12开启开发者工具,发现前端的请求只有下方两个属性,因此进行修改

@Data
public class EmployeePasswordDTO {private String newPassword;private String oldPassword;
}

因为这个业务涉及到如果员工的旧密码输入不对,那么无法进行一个密码的修改,因此需要定义一个常量OLD_PASSWORD_ERROR和将修改方法的类型设计为boolean类型,不是void类型

/*** 信息提示常量类*/
public class MessageConstant {public static final String OLD_PASSWORD_ERROR = "旧密码输入错误";
}
// Controller层/*** 修改密码* @param passwordDTO  密码DTO* @return  修改结果*/@PutMapping("/editPassword")@ApiOperation(value = "修改员工密码")public Result<String> updatePassword(@RequestBody EmployeePasswordDTO passwordDTO){log.info("修改密码:{}", passwordDTO);if (!employeeService.updatePassword(passwordDTO))return Result.error(MessageConstant.OLD_PASSWORD_ERROR);return Result.success();}
// ServiceImpl层/*** 修改员工密码** @param passwordDTO  员工密码信息*/@Overridepublic boolean updatePassword(EmployeePasswordDTO passwordDTO) {Long empId = BaseContext.getCurrentId();Employee employee = employeeMapper.getById(empId);String oldPassword = DigestUtils.md5DigestAsHex(passwordDTO.getOldPassword().getBytes());if (!employee.getPassword().equals(oldPassword)) {return false;}employee.setPassword(DigestUtils.md5DigestAsHex(passwordDTO.getNewPassword().getBytes()));employee.setUpdateTime(LocalDateTime.now());employee.setUpdateUser(empId);employeeMapper.update(employee);return true;}

这里ServiceImpl没有做很多解释,有涉及MD5密码的一个不可逆,更新时间以及更新用户的修改,MySQL的修改的语句等这些内容,大家自己看看代码吧,如果是在看不懂,那么评论提出疑问,看到就会即时回复给大家

至于这个继承的接口层就不详细放出,如果这个不会,那么这个博客没有看的必要,先打好基础

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

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

相关文章

焊接自动化测试平台图像处理分析-模型训练推理

1、使用技术栈&#xff1a;jdk17/springboot/python/opencv/yolov8 2、JAVA环境搭建 JDK17下载安装&#xff1a;wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz 解压软件 tar -xf jdk-17.0.16_linux-x64_bin.tar.gz 配置全局变量 vim /etc/p…

【python实用小脚本-205】[HR揭秘]手工党逐行查Bug的终结者|Python版代码质量“CT机”加速器(建议收藏)

1. 场景故事 “作为HR&#xff0c;我曾用2小时逐行审阅50份Python简历项目&#xff0c;直到发现候选人的代码复杂度超标导致线上事故…” → 转折点&#xff1a;用麦凯布&#xff08;McCabe&#xff09;圈复杂度检测脚本&#xff0c;30秒扫描全仓库&#xff0c;现可100%拦截“高…

LeetCode - 1089. 复写零

题目 1089. 复写零 - 力扣&#xff08;LeetCode&#xff09; 思路 这道题我首先想到的是从前往后双指针&#xff0c;但是这样做会造成数据的覆盖&#xff0c;比如说下面的这个情况 所以解决的方法就是从后往前去复写&#xff0c;但是从后往前的话就要知道最后一个有效元素是…

c#中public类比博图

简单来说&#xff0c;**public 定义了“接口”或“引脚”**&#xff0c;就像你的FB块上的 Input, Output, InOut 管脚一样。它决定了外部的其他代码&#xff08;如另一个FB或OB1&#xff09;可以看到和操作这个块里的什么东西。让我用你最熟悉的博图概念来详细类比一下。---###…

K8s基于节点软亲和的高 CPU Pod 扩容与优先调度方案

场景与目标 集群节点&#xff1a;master&#xff08;4 核&#xff09;、node1&#xff08;16 核&#xff09;、node2&#xff08;16 核&#xff09;。目标&#xff1a;将一个高 CPU 消耗的工作负载横向扩展到 4 个实例&#xff0c;并通过**节点亲和性&#xff08;软亲和&#…

MySQL InnoDB 的锁机制

引言 锁是数据库管理并发访问的另一种核心机制&#xff0c;与 MVCC 相辅相成。本文将系统梳理 MySQL InnoDB 中锁的粒度、类型和工作原理&#xff0c;并深入探讨它如何与事务隔离级别配合&#xff0c;共同保障数据的一致性和完整性。 一、 锁的粒度&#xff1a;由粗到细 InnoD…

状态模式(State Pattern)——网络连接场景的 C++ 实战

一、为什么要用状态模式&#xff1f;在开发中&#xff0c;经常遇到“对象在不同状态下行为不同”的情况。最常见的写法是用一堆 if/else 或 switch 来判断状态&#xff0c;然后在不同分支里写逻辑。这样做有两个问题&#xff1a;状态增多后&#xff0c;条件分支会变得臃肿。修改…

使用csi-driver-nfs实现K8S动态供给

文章目录一、部署NFS二、k8s环境部署csi-nfs三、测试动态供给补充应用服务器IPnfs-server192.168.1.5k8s-master01192.168.1.1k8s-node01192.168.1.2k8s-node02192.168.1.3 一、部署NFS 1、在NFS服务端和k8s所有节点部署nfs-utils 因为客户端去挂载nfs服务端的共享目录时&…

【开题答辩全过程】以 基于ssm的房屋中介管理系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

MySQL主从复制之进阶延时同步、GTID复制、半同步复制完整实验流程

1.主从同步1.1主从同步原理是指将主库的DDL和DML操作通过二进制日志(binlog)传到从库服务器&#xff0c;然后在从库上对这些日志进行重新执行&#xff0c;从而使从库和主库数据保持一致1.2环境设置库名ip地址操作系统mysql版本主库msyql-master192.168.31.228rhel7.9源码安装my…

织信低代码:用更聪明的方式,把想法变成现实!

你有没有过这样的时刻&#xff1f;想亲手做一个应用&#xff0c;却因为“不会编码”而迟迟没有开始&#xff1b;或曾无奈地目睹公司里一个看似简单的需求&#xff0c;硬是耗费数月、投入大量人力反复开发……现在&#xff0c;有一类工具正在改变这一切。它叫低代码。而今天我们…

【序列晋升】28 云原生时代的消息驱动架构 Spring Cloud Stream的未来可能性

目录 一、Spring Cloud Stream是什么&#xff1f; 二、诞生背景与设计动机 2.1 微服务架构的挑战 2.2 Spring生态的发展 2.3 Spring Integration的演进 三、架构设计与核心组件 3.1 分层架构设计 3.2 核心组件详解 3.3 编程模型 四、解决的问题与优势 4.1 解决的核心…

内网后渗透攻击--linux系统(权限维持)

用途限制声明&#xff0c;本文仅用于网络安全技术研究、教育与知识分享。文中涉及的渗透测试方法与工具&#xff0c;严禁用于未经授权的网络攻击、数据窃取或任何违法活动。任何因不当使用本文内容导致的法律后果&#xff0c;作者及发布平台不承担任何责任。渗透测试涉及复杂技…

C++笔记之同步信号量、互斥信号量与PV操作再探(含软考题目)

C++笔记之同步信号量、互斥信号量与PV操作再探(含软考题目) code review! 参考笔记: 1.C++笔记之同步信号量、互斥信号量与PV操作再探(含软考题目) 2.C++笔记之信号量、互斥量与PV操作 参考链接 1.嵌入式基础知识-信号量,PV原语与前趋图 2.信号量、PV操作及软考高级试题解析…

布隆过滤器:快速判断某个元素是否存在

特点&#xff1a;高效、空间占用小、允许一定误判 布隆过滤器在 Redis 里的实现机制&#xff0c;核心就是&#xff1a;用一个大位图&#xff08;bitmap&#xff09;来表示集合 位图长度 m 初始值都是 0 插入元素时通过 k 个不同的哈希函数&#xff0c;对元素做哈希 每个哈希结…

C# 修改基类List中某一元素的子类类型

描述&#xff1a;基类&#xff1a;BaseClass子类1&#xff1a;A子类2&#xff1a;B然后我有一个List<BaseClass>类型的链表:list&#xff0c;我先往list中添加了两个元素&#xff1a;第一个元素为A类型&#xff0c;第二个元素为B类型&#xff0c;然后我想改变第一个元素类…

基于STM32智能阳台监控系统

基于STM32智能阳台监控系统&#xff08;程序&#xff0b;原理图元件清单&#xff09;功能介绍具体功能&#xff1a;1.采用STM32作为主控芯片实现检测和控制&#xff1b;2.通过光敏电阻采集光线&#xff0c;将当前光线值在LCD1602显示&#xff0c;低于50%控制LED亮&#xff0c;高…

动态维护有效区间:滑动窗口

右指针不断移动获取解&#xff0c;左指针不断移动缩小解范围 左指针的意义非常重要&#xff0c;相当于一个标兵&#xff0c;不断与这个标兵进行比较&#xff0c;如果符合要求&#xff0c;这左指针进行移动&#xff0c;并进行操作&#xff0c;如果不符合要求&#xff0c;则左指针…

嵌入式学习---(单片机)

1.UART的概念通用异步收发器&#xff0c;2个串口&#xff08;1个串口被用于ISP下载程序&#xff0c;1个串口被用于和主机之间的通信&#xff09;&#xff0c;RXD(接收信号线) TXD(发送信号线)2、单工、半双工、全双工概念对比维度单工&#xff08;Simplex&#xff09;半双工&am…

基于单片机的宠物屋智能系统设计与实现(论文+源码)

1设计思路本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c…