首页 > 其他分享 >后端学习Day02

后端学习Day02

时间:2024-04-01 22:34:59浏览次数:12  
标签:return Day02 param 员工 学习 employee employeeDTO id

项目来源:B站黑马程序员《苍穹外卖》
本帖仅为学习日志

目录

一、新增员工

(一)需求分析和设计

1.产品原型:

2.接口设计:

本项目约定:

  • 管理端发出的的请求,统一使用/admin作为前缀
  • 用户端发出的请求,统一使用/user作为前缀

3.数据库设计(employee表):

(二)代码开发

根据新增员工接口设计对应的DTO:

注意:当前端提交的数据和实体类中对应的属性差别比较大时,建议使用DTO来封装数据

  • Controller层
/**
 * 新增员工
 *
 * @return
 */
@PostMapping
@ApiOperation("新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO){
    log.info("新增员工:{}",employeeDTO);
    //调用Service层新增员工
    employeeService.save(employeeDTO); //alt+enter 扩展方法
    return Result.success();
}
  • Service层
/**
 * 新增员工
 * @param employeeDTO
 * @return
 */
void save(EmployeeDTO employeeDTO);
/**
 * 新增员工
 * @param employeeDTO
 * @return
 */
public void save(EmployeeDTO employeeDTO){
    Employee employee = new Employee();
    //employee.setName(employeeDTO.getName());
    //使用对象属性拷贝,一次性将employeeDTO中的数据拷贝到employee中
    BeanUtils.copyProperties(employeeDTO,employee); //employeeDTO为源,employee为目标
    //设置账号的状态,默认正常状态 1表示正常 0表示锁定
    employee.setStatus(StatusConstant.ENABLE);
    //设置密码,默认密码123456
    employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
    //设置当前记录的创建时间和修改时间
    employee.setCreateTime(LocalDateTime.now());
    employee.setUpdateTime(LocalDateTime.now());
    //设置当前记录创建人id和修改人id
    // TODO 需要改为当前登录用户id
    employee.setCreateUser(10L);
    employee.setUpdateUser(10L);
    employeeMapper.insert(employee);
}
  • Mapper层
/**
 * 插入员工数据
 * @param employee
 */
@Insert("insert into employee (name,username, password, phone, sex, id_number, create_time, update_time, create_user, update_user, status) values" +
        "(#{name}, #{username}, #{password}, #{phone}, #{sex}, #{idNumber}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser}, #{status})")
void insert(Employee employee);

(三)功能测试

功能测试方法:

  • 通过接口文档测试
  • 通过前后端联调测试

注意:由于开发阶段前端和后端是并行开发的,后端完成某个功能后,此时前端对应的功能可能还没有开发完成,导致无法进行前后端联调测试。所以在开发阶段,后端测试主要以接口文档测试为主。

进行登录测试获取token,并将其存储为全局参数

接口文档测试成功

前后端联调测试成功

(四)代码完善

当前问题:

  • 录入的用户名已存在,抛出异常后没有处理

/**
 * 处理SQL异常
 * @param ex
 * @return
 */
@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
    //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);
    }
}

  • 新增员工时,创建人id和修改人id设置了固定值

ThreadLocal并不是一个Thread,而是一个Thread的局部变量。
ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外无法访问。

ThreadLocal常用方法:

  • public void set(T value) 设置当前线程的线程局部变量的值
  • public T get() 返回当前线程所对应的线程局部变量的值
  • public void remove() 移除当前线程的线程局部变量
    //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);
        //3、通过,放行
        return true;
    } catch (Exception ex) {
        //4、不通过,响应401状态码
        response.setStatus(401);
        return false;
    }
    //设置当前记录创建人id和修改人id
    employee.setCreateUser(BaseContext.getCurrentId());
    employee.setUpdateUser(BaseContext.getCurrentId());

二、员工分页查询

(一)需求分析和设计

产品原型:

业务规则:

  • 根据页码展示员工信息
  • 每页展示10条数据
  • 分页查询时可以根据需要,输入员工姓名进行查询

接口设计:

根据分页查询接口设计对应的DTO:

分页查询统一封装成PageResult对象:

员工信息分页查询后端返回的对象类型为:Result< PageResult>

(二)代码开发

pageHelper: 实现分页查询的mybatis插件

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
  • Controller
/**
 * 员工分页查询
 * @param employeePageQueryDTO
 * @return
 */
@GetMapping("/page")
@ApiOperation("员工分页查询")
public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
    log.info("员工分页查询,参数为:{}",employeePageQueryDTO);
    PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);
    return Result.success(pageResult);
}

*Server

/**
 * 分页查询
 * @param employeePageQueryDTO
 * @return
 */
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
    // select * from employee limit 0,10
    //开始分页查询
    PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
    Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);
    long total = page.getTotal();
    List<Employee> records = page.getResult();
    return new PageResult(total,records);
}

*Mapper

/**
 * 分页查询
 * @param employeePageQueryDTO
 * @return
 */
PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
<!-- 动态xml -->
<select id="pageQuery" resultType="com.sky.entity.Employee">
    select * from employee
    <where>
        <if test="name != null and name != ''">
            and name like concat("%",#{name},"%")
        </if>
    </where>
    order by create_time desc
</select>

(三)功能测试

注:token有效时间为2小时。

# 设置jwt过期时间
admin-ttl: 7200000

接口文档测试成功

(四)代码完善

时间显示有问题

解决方式:

  • 方式一:在属性上加入注释,对日记进行格式化
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;

只能处理单一属性

  • 方式二:在WebMvcConfiguration中扩展Spring MVC的消息转换器,统一对日期类型进行格式化处理
/**
 * 扩展Spring MVC框架的消息转换器
 * @param converters
 */
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    log.info("开始设置消息转换器...");
    //创建一个消息转换器对象
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
    converter.setObjectMapper(new JacksonObjectMapper());
    //将消息转换器添加到集合中
    //优先使用自定义的消息转换器
    converters.add(0,converter);
}

三、启用禁用员工账号

(一)需求分析和设计

产品原型:

业务规则:

  • 可以对状态为“启用”的员工账号进行“禁用”操作,反之亦可
  • 状态为“禁用”的员工账号不能登陆系统

接口设计:

(二)代码开发

该接口不涉及查询,不需要泛型

  • Controller层
/**
 * 启用/禁用员工账号
 * @param status
 * @param id
 * @return
 */
@PostMapping("/status/{status}")
@ApiOperation("启用/禁用员工账号")
public Result startOrStop(@PathVariable Integer status,Long id){
    log.info("启用/禁用员工账号:{},()",status,id);
    employeeService.startOrStop(status,id);
    return Result.success();
}

*Server层

/**
 * 启用/禁用员工账号
 * @param status
 * @param id
 */
void startOrStop(Integer status, Long id);
/**
 * 启用/禁用员工账号
 * @param status
 * @param id
 */
public void startOrStop(Integer status,Long id){
    // update employee set status = ? where id = ?

/* Employee employee = new Employee();
employee.setStatus(status);
employee.setId(id);*/

    //使用builder实现更简洁的构造
    Employee employee = Employee.builder()
            .status(status)
            .id(id)
            .build();
    employeeMapper.update(employee);
}
  • Mapper层
/**
 * 根据主键动态修改属性
 * @param employee
 */
// 使用动态sql
void update(Employee employee);
<update id="update" parameterType="Employee">
    update employee
    <set>
        <if test="name != null and name != ''"> name = #{name}, </if>
        <if test="username != null and username != ''"> username = #{username}, </if>
        <if test="password != null and password != ''"> password = #{password}, </if>
        <if test="phone != null and phone != ''"> phone = #{phone}, </if>
        <if test="sex != null">sex = #{sex},</if>
        <if test="idNumber != null and idNumber != ''"> id_number = #{idNumber}, </if>
        <if test="status != null">status = #{status},</if>
        <if test="updateTime != null">update_time = #{updateTime},</if>
        <if test="updateUser != null">update_user = #{updateUser},</if>
    </set>
    <where>
        id = #{id}
    </where>
</update>

(三)功能测试

接口测试:

前后端联调测试:


四、编辑员工

(一)需求分析和设计

产品原型:

编辑员工功能涉及两个接口

  • 根据id查询员工信息
  • 编辑员工信息



(二)代码开发

根据id查询员工信息接口

  • Controller层
/**
 * 根据id查询员工信息
 * @param id
 * @return
 */
@GetMapping("/{id}")
@ApiOperation("根据id查询员工信息")
public Result<Employee> getById(@PathVariable Long id){
    Employee employee = employeeService.getById(id);
    return Result.success(employee);
}

*Server层

/**
 * 根据id查询员工
 * @param id
 * @return
 */
Employee getById(Long id);
/**
 * 根据id查询员工
 * @param id
 * @return
 */
public Employee getById(Long id) {
    Employee employee = employeeMapper.getById(id);
    //将密码设置不可见
    employee.setPassword("******");
    return employee;
}
  • Mapper层
/**
 * 根据id查询员工信息
 * @param id
 * @return
 */
@Select("select * from employee where id = #{id}")
Employee getById(Long id);

编辑员工信息接口:

  • Controller层
/**
 * 编辑员工信息
 * @param employeeDTO
 * @return
 */
@PutMapping
@ApiOperation("编辑员工信息")
public Result update(@RequestBody EmployeeDTO employeeDTO){
    log.info("编辑员工信息:{}",employeeDTO);
    employeeService.update(employeeDTO);
    return Result.success();
}

*Server层

/**
 * 编辑员工信息
 * @param employeeDTO
 */
void update(EmployeeDTO employeeDTO);
/**
 * 编辑员工信息
 * @param employeeDTO
 */
public void update(EmployeeDTO employeeDTO) {
    Employee employee = new Employee();
    BeanUtils.copyProperties(employeeDTO,employee);
    employee.setUpdateTime(LocalDateTime.now());
    employee.setUpdateUser(BaseContext.getCurrentId());
    employeeMapper.update(employee);
}

(三)功能测试

根据id查询员工信息:
接口文档测试:

前后端联调测试:

编辑员工信息:
接口文档测试:

前后端联调测试:

五、导入分类模块功能代码

(一)需求分析

产品原型:

业务规则:

  • 分类名称必须是唯一
  • 分类按照类型可以分为菜品分类套餐分类
  • 新添加的分类状态默认为“禁用

接口设计:

  • 新增分类
  • 分类分页查询
  • 根据id删除分类
  • 修改分类
  • 启用/禁用分类
  • 根据类型查询分类

数据库设计(category表):

(二)代码导入

(三)功能测试

标签:return,Day02,param,员工,学习,employee,employeeDTO,id
From: https://www.cnblogs.com/overlord-lxy/p/18106220/lxy20240401

相关文章

  • 网络流学习笔记
    网络流的核心在于建图。建图建出来之后,剩下的基本上只是模板了。1基本定义一个网络是一张有向图\((V,E)\),其中每条边都有一个流量\(c(u,v)\)。一个网络有一个源点\(S\)和一个汇点\(T\)。网络流满足以下几条性质:流函数\(f:(x,y)\rightarrow\text{R}\)是一个二......
  • 学习-Java顺序结构之字符变换之大小写字母转换
    任务描述本关任务:将键盘输入的大写字母转化为小写字母。相关知识为了完成本关任务,你需要掌握:字符型变量和常量;字符型数据的加减运算;字符型数据的输入/输出。字符型变量和常量在之前我们学习了整型和浮点型的变量和常量,接下来介绍字符型的变量和常量。首先我们要先了解......
  • while、for循环学习
    练习1、列举你所知道的python所有基本数据类型及各自特征数字类型整数类型浮点数类型字符串类型列表类型字典类型布尔类型元组类型集合类型2、说说你所知道的运算符有哪些【一】算术运算符【二】比较运算符【三】赋值运算符【四】逻辑运算符【五】成员运算符......
  • OpenStack学习笔记03-OpenStack环境准备
    OpenStack学习笔记03-OpenStack环境准备OpenStackLinux对着《云操作系统(OpenStack)》第三章做的。一、系统环境配置1.为什么NAT模式网关不能填写XX.XX.XX.1?两天了,被这个问题纠缠两天了。虚拟机设置的是NAT模式,但是就是上不了外网。就是因为我把VMWare的NAT的网关改在了X......
  • 深入学习MySQL1——体系结构、常见引擎、索引
    MySQL体系结构连接层:提供一些mysql的数据连接对象、用户校验、权限认证等服务服务层:在本层实现了一些核心功能,如SQL接口,缓存查询(8.0之后的版本已取消该功能)、SQL分析和优化,部分内置函数的执行。所有的跨存储引擎的功能都在这一层实现,如:过程、函数等。在该层,服务器会解析查询并......
  • 学习嵌入式的第三天
    学习嵌入式的第三天数据类型获取数据类型存储的大小sizeof运算符可计算出指定数据(变量,常量)的字节大小它的结果是size_t类型的数据(本质上就是unsignedint或unsingnedlong类型又系统和编译器决定),对应的占位符是%zu数据类型的转换数据类型的隐式转换整数自动......
  • Node.js毕业设计基于HarmonyOS在线学习平台app(Express+附源码)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的迅猛发展,移动应用已经成为了人们获取信息、学习知识的重要渠道。在线学习平台作为现代教育技术的重要组成部分,为人们提供了便捷的学习途径......
  • HTML学习归纳1
            想通过这样的方式,记录自己的学习过程。将近期学习到的一些内容,不定期的做一些总结,方便有相同经历的人一起学习交流。    首先,在初步了解学习了HTML以后,先明白这是一门标签语言,逻辑架构上应该说是十分清晰的,我们需要的是掌握不同标签的用法。   ......
  • 基于阿基米德优化算法优化的核极限学习机(KELM)回归预测
    基于阿基米德优化算法优化的核极限学习机(KELM)回归预测文章目录基于阿基米德优化算法优化的核极限学习机(KELM)回归预测1.KELM理论基础2.回归问题数据处理4.基于阿基米德优化算法优化的KELM5.测试结果6.Matlab代码摘要:本文利用阿基米德优化算法对核极限学习机(KELM......
  • 基于寄生捕食算法优化的核极限学习机(KELM)回归预测
    基于寄生捕食算法优化的核极限学习机(KELM)回归预测文章目录基于寄生捕食算法优化的核极限学习机(KELM)回归预测1.KELM理论基础2.回归问题数据处理4.基于寄生捕食算法优化的KELM5.测试结果6.Matlab代码摘要:本文利用寄生捕食算法对核极限学习机(KELM)进行优化,并用于......