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

黑马苍穹外卖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里操作)
导入完手动编译一下
在这里插入图片描述

相关文章:

  • Python爬取与可视化-豆瓣电影数据
  • 前端根据权限生成三级路由
  • Linux | grep命令和 find命令有什么区别
  • 齐普夫定律在循环神经网络中的语言模型的应用
  • 6.17作业
  • Spring Boot高级配置与自定义Starter详解
  • 哪个充电宝牌子好用又实惠?盘点四大平价充电宝分享
  • YOLOv10涨点改进:改进检测头(Partial_C_v10Detect)检测头结构创新,实现涨点
  • 微信小程序录音机源代码
  • 中标新领域!亚信科技+用友网络,将助力广西某市城投集团玩转“人事”
  • 【Linux】版本
  • MySQL中的一行记录是怎么存储的
  • 【QT5】<重点> QT串口编程
  • Java 和 Kotlin Lambda 表达式详解
  • vue简介实例
  • 时间复杂度分析经典问题——最大子序列和
  • 收藏网友的 源程序下载网
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 11111111
  • HTTP那些事
  • HTTP--网络协议分层,http历史(二)
  • Java 内存分配及垃圾回收机制初探
  • Java 最常见的 200+ 面试题:面试必备
  • JavaScript服务器推送技术之 WebSocket
  • Java多线程(4):使用线程池执行定时任务
  • leetcode386. Lexicographical Numbers
  • MD5加密原理解析及OC版原理实现
  • mysql innodb 索引使用指南
  • MySQL用户中的%到底包不包括localhost?
  • Python - 闭包Closure
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • SAP云平台里Global Account和Sub Account的关系
  • SpringCloud集成分布式事务LCN (一)
  • springMvc学习笔记(2)
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • Vue.js源码(2):初探List Rendering
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • windows-nginx-https-本地配置
  • 测试如何在敏捷团队中工作?
  • 从0到1:PostCSS 插件开发最佳实践
  • 关于Java中分层中遇到的一些问题
  • 机器学习中为什么要做归一化normalization
  • 基于axios的vue插件,让http请求更简单
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 算法-图和图算法
  • 推荐一个React的管理后台框架
  • 我建了一个叫Hello World的项目
  • 新版博客前端前瞻
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 主流的CSS水平和垂直居中技术大全
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • 数据库巡检项
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...