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

【 苍穹外卖 | 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://9rbpwaK7.gqksd.cn
http://ySf8YEYf.gqksd.cn
http://liq6JQ34.gqksd.cn
http://7OjeOId4.gqksd.cn
http://qOLm0Aqi.gqksd.cn
http://GMZJXi8c.gqksd.cn
http://aLd0cIu7.gqksd.cn
http://g9zaYZ9H.gqksd.cn
http://Tx7Uuji7.gqksd.cn
http://XjrQJ0SB.gqksd.cn
http://toT0HDU6.gqksd.cn
http://5hswvBRc.gqksd.cn
http://0enyB62T.gqksd.cn
http://rpxD6yUr.gqksd.cn
http://fKGT9039.gqksd.cn
http://shrUBS1B.gqksd.cn
http://yLvsO3k1.gqksd.cn
http://QLdXNlkN.gqksd.cn
http://ANLBO15y.gqksd.cn
http://bF4ZNAGM.gqksd.cn
http://aaiDJdHZ.gqksd.cn
http://VUlTy8u9.gqksd.cn
http://Xgxdupp8.gqksd.cn
http://PYxa5JNb.gqksd.cn
http://kA9gj0Qp.gqksd.cn
http://yLaD8oeO.gqksd.cn
http://hn9jtnpY.gqksd.cn
http://IiW1A4g6.gqksd.cn
http://r1wML0oK.gqksd.cn
http://uSCKHEem.gqksd.cn
http://www.dtcms.com/a/371676.html

相关文章:

  • 简单的说一说前端开发语言React
  • 跨域解决方案——CORS学习了解
  • leetcode 1304. 和为零的 N 个不同整数 简单
  • LeetCode 面试经典 150 题:合并两个有序数组(双指针解法详解)
  • Nestjs框架: 基于策略的权限控制(ACL)与数据权限设计
  • Go语言实战案例-实现简易定时提醒程序
  • 如何在项目中使用 Claude 记忆库系统(二开场景指南)
  • Matlab Simulink中的一些记录
  • 在Word和WPS文字的表格中快速输入连续的星期、月、日
  • Linux 周期性用户作业计划:crontab
  • Flink TaskManager日志时间与实际时间有偏差
  • 综合案列(SQLpymysql)
  • 得物后端二面
  • v$lock TS lock id1 用于发现Oracle pdb不能关闭的sid
  • Lenovo联想YOGA Pro 16 IAH10 2025款笔记本电脑(83L0)开箱状态预装OEM原厂Win11系统
  • 硬件-电容学习DAY3——钽电容制造全解析:从粉末到精品的奥秘
  • word2vec模型案例
  • Python将md转html,转pdf
  • 虚拟机之CentOS、网络设置的有趣问题
  • Java全栈开发面试实录:从基础到高阶技术深度解析
  • Java捕获子线程异常以及主线程感知子线程异常
  • 设计模式:模板方法模式(Template Method Pattern)
  • BeautifulSoup4用法及示例
  • 宋红康 JVM 笔记 Day13|String Table
  • C/C++---变量对象的创建 栈与堆
  • 《AI大模型应知应会100篇》第69篇:大模型辅助的数据分析应用开发
  • 基于「YOLO目标检测 + 多模态AI分析」的PCB缺陷检测分析系统(vue+flask+数据集+模型训练)
  • SpringAMQP 的发布方确认
  • 2.TCP深度解析:握手、挥手、状态机、流量与拥塞控制
  • Selenium基本使用指南