黑马苍穹外卖2 员工的增查改+异常处理+ThreadLocal

员工管理

新增员工

在这里插入图片描述
在这里插入图片描述
Controller:

  @PostMapping//post类型的请求@ApiOperation("添加员工")public Result save(@RequestBody EmployeeDTO employeeDTO) {log.info("新增员工{}", employeeDTO);employeeService.save(employeeDTO);return Result.success();}

代码完善–存在问题

在这里插入图片描述
问题1.控制台抛出异常,程序处理。使用全局异常处理器
处理sql异常 Duplicate entry 'zhangsan’ for key 'employee.idx username
全局异常处理器:GlobalExceptionHandler.java

@ExceptionHandlerpublic Result exceptionHandler(SQLIntegrityConstraintViolationException ex) {//处理sql异常 Duplicate entry 'zhangsan’ for key 'employee.idx usernameString message = ex.getMessage();if (message.contains("Duplicate entry")) {String[] split = message.split(" ");String username = split[2];//拿到用户名String msg = username + MessageConstant.ALREADY_EXISTS;//用户名 已存在--为了规范使用,用个常量来引用return Result.error(msg);} else {return Result.error(MessageConstant.UNKNOWN_ERROR);//未知错误提示信息}}

问题2.
动态获取登录用户ID
先看一下基于JWT令牌认证流程
在这里插入图片描述
在这里插入图片描述

ThreadLocal

并不是一个thread,而是Thread的局部变量。
每个县城独享一份存储空间,具有线程隔离的效果,只有在县城内才能获取到对应的值,线程外不行。
客户端发起的每一次请求,Tomcat服务器会分配一个进程,然后单独的执行代码每次请求都是一个单独的线程
也就是在这个线程内能共享一份存储空间。
所以我们可以讲给当前用户ID存到这个空间内。
JwtTokenAdminInterceptor.java // JWT拦截器

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断当前拦截到的是Controller的方法还是其他资源if (!(handler instanceof HandlerMethod)) {//当前拦截到的不是动态方法,直接放行return true;}//1、从请求头中获取令牌String token = request.getHeader(jwtProperties.getAdminTokenName());//2、校验令牌try {log.info("jwt校验:{}", token);Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());log.info("当前员工id:{}", empId);BaseContext.setCurrentId(empId);//将ID放入线程空间//3、通过,放行return true;} catch (Exception ex) {//4、不通过,响应401状态码response.setStatus(401);return false;}}

上图就是调用这个方法类将员工ID存到当前线程空间中。
下图是添加员工信息Service中的方法实现,重点在于从线程空间取出登录用户ID

Service:

public void save(EmployeeDTO employeeDTO) {Employee employee = new Employee();//提交给数据库的最好是entityBeanUtils.copyProperties(employeeDTO, employee);//进行一个属性复制//填充字段employee.setStatus(StatusConstant.ENABLE);employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));employee.setCreateTime(LocalDateTime.now());employee.setUpdateTime(LocalDateTime.now());//通过ThreadLocal获得当前用户的idemployee.setCreateUser(BaseContext.getCurrentId());employee.setUpdateUser(BaseContext.getCurrentId());employeeMapper.insert(employee);}

员工分页查询

在这里插入图片描述在这里插入图片描述
Controller:

 @GetMapping("/page")//get类型的请求@ApiOperation("员工分页查询")public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO) {//数据不是json,不需要注解PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);return Result.success(pageResult);}

PageHelper插件来辅助代码
Service:

@Overridepublic PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {//select * from employee linit 0,10//调用PageHelper 开始分页查询                    页码,每页记录数PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());Page<Employee> page = employeeMapper.selectByPage(employeePageQueryDTO);//返回的是Page//接下来处理一下,变成pageresult,需要两个参数long total = page.getTotal();List<Employee> result = page.getResult();return new PageResult(total, result);}

mapper:
不用注解,动态sql使用映射文件
在resource文件夹里都是xml文件

<select id="selectByPage" resultType="com.sky.entity.Employee">select * from employee<where><if test="name!=null and name !='' ">and name like concat('%',#{name},'%') <!--模糊查询 like --></if></where>order by create_time desc <!--创建时间降序-->
</select>

在这里插入图片描述
方式一:在实体类里加

//@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime updateTime;

方式二:扩展消息转换器,在配置类中
重写父类方法

protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {//创建一个消息转换器MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();//需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据converter.setObjectMapper(new JacksonObjectMapper());//将自己的消息转化器加入容器中converters.add(0, converter);//0为索引,让这个转换器排前面}

启用禁用员工账号

在这里插入图片描述
Controller:

@PostMapping("/status/{status}")@ApiOperation("启用禁用员工账号")public Result startOrStop(@PathVariable("status") Integer status, Long id) {employeeService.startOrStop(status, id);return Result.success();}

Service:本质是修改员工Status 即update

public void startOrStop(Integer status, Long id) {Employee employee =//本质就是创建一个实体类对象Employee.builder()// 构建器对象.id(id)// 方法名和属性名一致.status(status).build();employeeMapper.update(employee);}

根据主键动态修改,所以又到xml里

<!--因为在yml文件中声明了别名包的扫描,所以此处可以不使用全类名--><update id="update" parameterType="Employee">update employee<set><if test="name != null">name = #{name},</if><if test="username != null">username = #{username},</if><if test="password != null">password = #{password},</if><if test="phone != null">phone = #{phone},</if><if test="sex != null">sex = #{sex},</if><if test="idNumber != null">id_number = #{idNumber},</if><if test="updateTime != null">update_time = #{updateTime},</if><if test="updateUser != null">update_user = #{updateUser},</if><if test="status != null"> status = #{status},</if></set>where id = #{id}</update>

编辑员工

在这里插入图片描述
在这里插入图片描述
查询员工信息:

@GetMapping("/{id}")@ApiOperation("根据Id查询员工")public Result<Employee> getById(@PathVariable Long id) {//加个路径参数的注解@PathVariable来得到idEmployee employee = employeeService.getById(id);return Result.success(employee);}
@Overridepublic Employee getById(Long id) {Employee employee = employeeMapper.getById(id);employee.setPassword("****");// 查出的密码,给前端传****return employee;}
@Select("select * from employee where id=#{id}")Employee getById(Long id);

编辑员工信息:

@PutMapping@ApiOperation("编辑员工信息")public Result update(@RequestBody EmployeeDTO employeeDTO) {employeeService.update(employeeDTO);return Result.success();}
public void update(EmployeeDTO employeeDTO) {Employee employee = new Employee();//对象属性拷贝BeanUtils.copyProperties(employeeDTO,employee);employee.setUpdateTime(LocalDateTime.now());employee.setUpdateUser(BaseContext.getCurrentId());employeeMapper.update(employee);}

导入分类模块功能代码

在这里插入图片描述
直接粘贴到对应文件夹(在IDEA里操作)
导入完手动编译一下
在这里插入图片描述

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

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

相关文章

有监督学习——梯度下降

1. 梯度下降 梯度下降&#xff08;Gradient Descent&#xff09;是计算机计算能力有限的条件下启用的逐步逼近、迭代求解方法&#xff0c;在理论上不保证下降求得最优解。 e.g. 假设有三维曲面表达函数空间&#xff0c;长(x)、宽(y)轴为子变量&#xff0c;高(z)是因变量&…

themleaf 页面弹层取值

themleaf 页面弹层取值 创作背景themleaf页面事件onbluronclick 页面参数提交 创作背景 个人在日常开发中&#xff0c;遇到了一个需求页面&#xff0c;页面交互较多&#xff0c;用到的事件也很丰富&#xff0c;特此记录&#xff0c;方便后续查找也方便有需要的开发者采用&…

软件测试期末复习

软件测试期末复习 Author 雨 2024年6月18日 1. 什么是软件测试 从一个通常为无限的执行域中选取合适的有限的测试用例&#xff0c;对程序所期望的行为进行动态验证的活动过程。 2. 软件测试的目的 尽早地发现软件的缺陷 3.什么是测试什么是缺陷 从软件内部看&#xff1a;软件开…

SpringCloudStream原理和深入使用

简单概述 Spring Cloud Stream是一个用于构建与共享消息传递系统连接的高度可扩展的事件驱动型微服务的框架。 应用程序通过inputs或outputs来与Spring Cloud Stream中binder对象交互&#xff0c;binder对象负责与消息中间件交互。也就是说&#xff1a;Spring Cloud Stream能…

探索Web Components

title: 探索Web Components date: 2024/6/16 updated: 2024/6/16 author: cmdragon excerpt: 这篇文章介绍了Web Components技术&#xff0c;它允许开发者创建可复用、封装良好的自定义HTML元素&#xff0c;并直接在浏览器中运行&#xff0c;无需依赖外部库。通过组合HTML模…

多尺度特征提取:原理、应用与挑战

多尺度 多尺度特征提取&#xff1a;原理、应用与挑战**原理****应用****挑战****总结** 多尺度特征提取&#xff1a;原理、应用与挑战 在计算机视觉、自然语言处理和信号处理等领域&#xff0c;有效地捕捉和解析数据的多种尺度特性是至关重要的。多尺度特征提取是一种技术&…

【机器学习】智能创意工厂:机器学习驱动的AIGC,打造未来内容新生态

&#x1f680;时空传送门 &#x1f50d;机器学习在AIGC中的核心技术&#x1f4d5;深度学习&#x1f388;生成对抗网络&#xff08;GANs&#xff09; &#x1f680;机器学习在AIGC中的具体应用&#x1f340;图像生成与编辑⭐文本生成与对话系统&#x1f320;音频生成与语音合成 …

SpringMVC01-初始SpringMVC

SpringMVC 回顾MVC 什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写&#xff0c;是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式&#xff0c;MVC是一种架构模…

高通Android 12 右边导航栏改成底部显示

最近同事说需要修改右边导航栏到底部&#xff0c;问怎么搞&#xff1f;然后看下源码尝试下。 1、Android 12修改代码路径 frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java a/frameworks/base/services/core/java/com/android/server/wm/Display…

【LeetCode:2786. 访问数组中的位置使分数最大 + 递归 + 记忆化缓存 + dp】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

电感的本质是什么

什么是电感&#xff1f; 电感器件一般是指螺线圈&#xff0c;由导线圈一圈靠一圈地绕在绝缘管上&#xff0c;绝缘管可以是空心的&#xff0c;也可以包含铁芯或磁粉芯。 为什么把’线’绕成’圈’就是电感&#xff1f; 电感的工作原理非常抽象&#xff0c;为了解释什么是电感…

IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照(snapshot)JAR 包

IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照&#xff08;snapshot&#xff09;JAR 包 目录 IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照&#xff08;snapshot&#xff09;JAR 包1. 检查 settings.xml2. IDEA Maven 配置3. 强制更新 Snapshot4. 使用…

使用 C# 学习面向对象编程:第 8 部分

抽象方法 亲爱的读者&#xff0c;本文是 OOP 的第四大支柱&#xff0c;也是最后一大支柱。对于 OOP 初学者来说&#xff0c;这很容易让人困惑。因此&#xff0c;我们用非常简单的语言提供了一个示例。 “抽象用于管理复杂性。无法创建抽象类的对象。抽象类用于继承。” 例如…

端口映射工具下载?

天联是一款强大的端口映射工具&#xff0c;它能够帮助用户实现远程数据采集管理、异地统一管理、随时随地协同办公等多种场景的应用。无论您是医药、餐饮、商超等零售行业的企业&#xff0c;还是需要使用OA、CRM、ERP、财务进销存等系统的企业&#xff0c;甚至是使用视频监控设…

Python自动化测试面试题精选(一)

今天大家介绍一些Python自动化测试中常见的面试题&#xff0c;涵盖了Python基础、测试框架、测试工具、测试方法等方面的内容&#xff0c;希望能够帮助你提升自己的水平和信心。 项目相关 什么项目适合做自动化测试&#xff1f; 答&#xff1a;一般来说&#xff0c;适合做自…

前端菜鸡流水账日记 -- git管理工具(多版本)

哈喽哇&#xff0c;我又又又来了&#xff0c;其实之前就挺想进行一篇关于git管理工具的分享的&#xff0c;但是一直都没有来的及&#xff0c;直到今天&#xff0c;在学习的时候&#xff0c;&#xff0c;一个朋友新发现了一个vscode中的小插件&#xff0c;所以我就决定一起来分享…

Github入门教程,适合新手学习(非常详细)

前言&#xff1a;本篇博客为手把手教学的 Github 代码管理教程&#xff0c;属于新手入门级别的难度。教程简单易操作&#xff0c;能够基本满足读者朋友日常项目寄托于 Github 平台上进行代码管理的需求。Git 与 Github 是一名合格程序员 coder 必定会接触到的工具与平台&#x…

React+TS前台项目实战(十)-- 全局常用组件CopyText封装

文章目录 前言CopyText组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲项目常用复制文本组件封装&#xff0c;这个组件是一个用于拷贝文本的 React 组件&#xff0c;它提供了拷贝&#xff0c;国际化和消息提示的功能 CopyText组件 1. 功能分…

linux远程访问及控制

补充&#xff1a; 终端&#xff1a;接收用户的指令 TTY终端 虚拟终端 ssh:22端口号&#xff0c;加密。 telnet&#xff1a;23端口号&#xff0c;不加密。 解释器&#xff1a;shell SSH 远程管理 SSH&#xff08;Secure Shell&#xff09;是一种安全通道协议&#xff0c…

012.指纹浏览器编译-修改canvas指纹(高级)

指纹浏览器编译-修改canvas指纹(高级) 一、canvas指纹是什么 之前介绍过canvas指纹和常见网站绕过canvas指纹&#xff0c;插眼&#xff1a; https://blog.csdn.net/w1101662433/article/details/137959179 二、为啥有更高级的canvas指纹 众所周知&#xff0c;creepjs和brow…