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

news2024/10/7 10:18:40

员工管理

新增员工

在这里插入图片描述
在这里插入图片描述
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

@ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        //处理sql异常 Duplicate entry 'zhangsan’ for key 'employee.idx username
        String 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();
        //提交给数据库的最好是entity
        BeanUtils.copyProperties(employeeDTO, employee);//进行一个属性复制

        //填充字段
        employee.setStatus(StatusConstant.ENABLE);
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
        employee.setCreateTime(LocalDateTime.now());
       employee.setUpdateTime(LocalDateTime.now());

        //通过ThreadLocal获得当前用户的id
        employee.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:

@Override
    public 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来得到id
        Employee employee = employeeService.getById(id);
        return Result.success(employee);
    }
@Override
    public 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.coloradmin.cn/o/1834131.html

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

相关文章

ASN.1语言详解(编码规则、关键字、符号、数据类型)

目录 一. ASN.1基本信息 ▐ ASN.1编码规则 二. ASN.1语法规范 ▐ ASN.1的关键字 ▐ ASN.1的符号 ▐ ASN.1的数据类型 ▐ 示例 一. ASN.1基本信息 ASN.1&#xff08;Abstract Syntax Notation One&#xff09;是一种国际标准&#xff08;由ITU-T X.680系列建议定义&#…

elasticsearch hanlp插件远程词典配置

elasticsearch hanlp插件远程词典配置 背景远程词典配置新增远程词典文件修改hanlp-remote.xml自动加载词典 远程词典测试 背景 在使用elasticsearch的过程中&#xff0c;总会遇到与分词相关的需求&#xff0c;这里将针对常用的elasticsearch hanlp&#xff08;后面统称为 es …

表单中的常用元素

10.图像形式上传文件 <input type“image”>定义图像形式的提交。 src 属性和alt属性必须与<input type“image””>结合使用。 input type"image"src"img/l.jpg"alt"submit"/> 11.下拉列表框 <select>标签定义下拉列表框…

java基础-IDEA环境基础用法自动导包等设置

IDEA&#xff1a; 是用于Java语言开发的集成环境&#xff0c;它是业界公认的目前用于Java程序开发最好的工具。 把代码编写&#xff0c;编译&#xff0c;执行&#xff0c;调试等多种功能综合到一起的开发工具。 IDEA项目结构&#xff1a; 多级包用 . 链接。 快速生成 快…

解锁工业自动化:通过CANopen转Profinet的无缝对接

通过开疆智能CanOpen转ProfiNet网关&#xff08;KJ-PNG-205&#xff09;实现&#xff0c;上位机能够直接与CANopen总线驱动器进行通信&#xff0c;以实时获取设备运行状态信息。具体过程为&#xff1a;上位机通过发送CanOpen协议命令到CanOpen转ProfiNet网关&#xff0c;然后由…

华为手环9省电设置

1、 手环开启熄屏显示续航约3天&#xff0c;原因为屏幕持续常亮显示&#xff1b;如不需要可通过手环“设置->表盘->熄屏显示”路径进行关闭&#xff1b; 2、 手环具备后台健康自动检测功能&#xff0c;您可根据需要选择是否使用或关闭&#xff1a; &#xff08;1&#x…

怎么将文档翻译免费导出?这些工具让你写论文更轻松

对于许多学生&#xff0c;啃下外文文献的难度有时甚至超过了写论文。查词费时&#xff0c;段落翻译又常受限于字数。 在线翻译工具&#xff0c;作为语言间的桥梁&#xff0c;正在学术和商业领域变得越来越重要。 下面&#xff0c;让我们快速浏览一些免费的文档翻译软件app&am…

css之浏览器兼容性

css之浏览器兼容性 内核 内核代表作品 兼容的概念和原因 Hack的副作用 常见的CSS Bug 多个图片在一起&#xff0c;图片套个盒子 图片在IE浏览器上有蓝色边框 解决办法&#xff1a;给img加上 border:0 表单元素中距离顶部元素不一样 左边input 右边button 解决办法&#x…

四款让人大开眼界的高质量软件,个个实力超群,使用起来爱不释手

电脑里的Windows软件&#xff0c;简直多得数不清&#xff0c;啥都有。 像那个电子表格、写文章的、玩游戏聊天的、还有修图的&#xff0c;这些都太常见了&#xff0c;它们确实给咱们生活带来方便&#xff0c;但有时候也会让那些不太懂电脑的小伙伴们头疼不已。 讲真&#xff0…

物联网协议应用

目录 前言一、NTP协议1.1 NTP简介1.2 NTP实现 二、HTTP协议2.1 HTTP协议简介2.2 HTTP服务器 三、MQTT协议3.1 MQTT协议简介3.1.1 MQTT通信模型3.1.2 MQTT协议实现原理3.1.3 MQTT 控制报文 3.2 移植MQTT协议 前言 本文主要介绍一下物联网协议如NTP协议、HTTP协议和MQTT协议的接口…

elementPlus渲染需要权限校验的图片

技术栈&#xff1a;elementPlusvue3 html部分&#xff1a; <el-image :style"{width:width,height:height}" ref"previewimg" :src"previewSrc"></el-image> js部分 /*** 预览图片* param {String} url [图片的地址]*/const showP…

飞腾派初体验(3)

“我心光明&#xff0c;夫复何言” - 王阳明。 朋友的题词&#xff0c;念念不忘 做人要厚道&#xff0c;挖坑就要填。说了要整labview&#xff0c;现在来还愿。 国内labview还是相对小众的东西&#xff0c;而且主要是大厂设备在用&#xff0c;同时NI原厂比较佛系&#xff08;欧…

企业邮箱大附件无法上传?无法确认接收状态?这样解决就行

Outlook邮箱作为最常用的邮箱系统&#xff0c;被全世界企业采用作为内部通用沟通方式&#xff0c;但Outlook邮箱却有着明显的使用缺陷&#xff0c;如邮箱大附件上传障碍及附件接收无提示等。 1、企业邮箱大附件无法上传 Outlook企业邮箱大附件的上传上限一般是50M&#xff0c;…

opencv c++ 检测图像尺寸大小,标注轮廓

1. 项目背景 本项目旨在开发一个图像处理程序&#xff0c;通过使用计算机视觉技术&#xff0c;能够自动检测图像中物体的尺寸并进行分类。项目利用了开源的计算机视觉库 OpenCV&#xff0c;实现了图像的灰度处理、二值化、轮廓检测、边界框绘制以及尺寸分类等功能。通过这些功…

Java控制语句——break和continue

系列文章目录 文章目录 系列文章目录前言一、【break的例子】二、【continue的例子】 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂…

003 AOP介绍

文章目录 什么是AOP为什么用AOPAOP相关术语介绍AOP实现之AspectJ(了解)AOP实现之Spring AOP(了解)JDK动态代理Cglib动态代理 什么是AOP 在软件业中&#xff0c;AOP为Aspect Oriented Programming的缩写&#xff0c;意为面向切面编程作用&#xff1a;在不修改目标类代码的前提下…

Ubuntu乌班图安装VIM文本编辑器工具

系列文章目录 Ubuntu-24.04-live-server-amd64安装界面中文版 Ubuntu-24.04-live-server-amd64启用ssh Ubuntu安装qemu-guest-agent 文章目录 系列文章目录前言一、安装VIM&#xff1f;二、VIM基本设置总结 前言 从centos转到Ubuntu发现默认安装没有vi 一、安装VIM&#xff1…

服务器部署开源大模型完整教程 Ollama+Gemma+open-webui

现在开源的大模型其实挺多的&#xff0c;今天搭建Gemma这个谷歌开源的大模型&#xff0c;但是你想搭建别的只要你看完你都会了。 介绍 Ollama&#xff1a;一款可以让你在本地快速搭建大模型的工具 官网&#xff1a;https://ollama.com/ github&#xff1a;https://github.c…

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

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

关于阿里云效流水线自动部署项目教程

1、登录阿里云效:阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台 2、点击左侧流水线&#xff1a; 3、在流水线界面&#xff0c;新建流水线 4、我的是php代码&#xff0c;因此选择php模版 5、创建之后添加流程线源&#xff0c;如下图 6、选择相应的源头。比…