苍穹外卖学习Day2

文章目录

    • 员工管理模块实现
      • 新增员工
        • 需求设计分析
        • 代码开发
        • 功能测试
        • 代码完善
      • 员工分页查询
        • 需求分析与设计
        • 代码开发
        • 功能测试
        • 代码完善
      • 启用禁用员工账号
        • 需求分析和设计
        • 代码开发
        • 功能测试
      • 编辑员工
        • 需求分析
        • 代码开发
      • 导入分类模块功能代码
        • 需求分析设计

员工管理模块实现

新增员工

需求设计分析

一般由产品经理设计,根据产品原型图来进行逻辑设计与开发。
苍穹外卖学习Day2_第1张图片
设计接口
苍穹外卖学习Day2_第2张图片
数据库设计
苍穹外卖学习Day2_第3张图片

代码开发

苍穹外卖学习Day2_第4张图片
在Controller层中代码

    /**
     *新增员工
     */
    @PostMapping
    @ApiOperation("新增员工")
    public Result save(@RequestBody EmployeeDTO employeeDTO){
        log.info("新增员工:{}",employeeDTO);
        employeeService.save(employeeDTO);
        return Result.success();
    }

接口类

    /**
     * 新增员工实现方法
     * @param employeeDTO
     */
    void save(EmployeeDTO employeeDTO);

实现类

   /**
     * 新增员工
     * @param employeeDTO
     */
    @Override
    public void save(EmployeeDTO employeeDTO) {
        Employee employee=new Employee();
        //对象属性拷贝,简化代码,前提属性名需要一致
        BeanUtils.copyProperties(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
        //TODO 后期需要改为当前登录用户的id,目前先要写死
        employee.setCreateUser(10L);
        employee.setUpdateUser(10L);

        employeeMapper.insert(employee);
    }

后端Mapper类

    /**
     * 插入员工数据
     * 数据库变量中默认kebab下划线命名方式(此为历史惯例),在Mybatis中需要通过yml进行驼峰命名转换符合变量命名习惯
     * @param employee
     */

    @Insert("insert into employee(name, username, password, phone, sex, id_number, status, create_time, update_time, create_user, update_user) " +
            "values " +
            "(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser})")
    void insert(Employee employee);
功能测试

开发阶段更多通过接口文档测试
在这里插入图片描述
使用接口文档进行测试
苍穹外卖学习Day2_第5张图片
苍穹外卖学习Day2_第6张图片

使用debug调试时初始会报401接口异常,是因为jwt令牌拦截未通过。
苍穹外卖学习Day2_第7张图片
那如何测试呢?
要先通过登录接口debug获取一个令牌
苍穹外卖学习Day2_第8张图片
通过左侧文档管理设置一个全局令牌,参数值即为登录接口所获得的令牌
苍穹外卖学习Day2_第9张图片
再重新进行debug测试数据已封装好
苍穹外卖学习Day2_第10张图片
插入成功
苍穹外卖学习Day2_第11张图片

代码完善

存在问题

  • 程序对用户名相同时的数据库异常没有处理。
    解决方法
    苍穹外卖学习Day2_第12张图片
    在这里插入图片描述

苍穹外卖学习Day2_第13张图片

  • 创建人,修改人ID设置为了固定的值
    解决方法苍穹外卖学习Day2_第14张图片在这里插入图片描述
    在拦截器中存入,service实现类中取出
            //在拦截器中存入
            BaseContext.setCurrentId(empId);
            //Controller层
        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());

员工分页查询

需求分析与设计

苍穹外卖学习Day2_第15张图片
苍穹外卖学习Day2_第16张图片
苍穹外卖学习Day2_第17张图片
苍穹外卖学习Day2_第18张图片

代码开发

controller层

    @GetMapping("/page")
    @ApiOperation("员工分页查询")
    public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
        log.info("员工分页查询参数为:{}", employeePageQueryDTO);
        PageResult pageResult=employeeService.pageQuery(employeePageQueryDTO);
        return Result.success(pageResult);
    }

Service实现类

    /**
     * 分页查询实现类
     * @param employeePageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        //select * from employee limit 0,10
        //使用PageHelper分页插件
        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中使用xml方式,动态SQL

    <select id="pageQuery" resultType="com.sky.entity.Employee">
        select  * from employee
        <where>
            <if test="name!=null and name!=''">
#             使用concat拼接字符串
                and name like concat('%',#{name},'%')
            if>
        where>
#         降序排序
        order by create_time desc
    select>
mapper>

同时复习一下动态SQL的知识

在MyBatis中,动态SQL是一种能够根据不同条件生成不同SQL语句的机制。这使得在查询、更新、插入或删除数据时,可以根据运行时的条件动态地构建SQL语句,而不是在静态的SQL语句中硬编码所有条件。动态SQL通过在XML映射文件中使用一些特定的元素来实现,这些元素允许根据条件包含或排除不同的SQL片段。
where标签:

where标签用于在生成SQL语句时提供一个条件判断块,它会自动去除首个条件之前的多余的AND或OR。这使得可以在使用动态SQL时更灵活地拼接条件,而无需过多的考虑首个条件是否需要添加AND或OR。

<select id="findUsers" parameterType="map" resultType="User">
    SELECT * FROM users
    <where>
        <if test="username != null">
            AND username = #{username}
        if>
        <if test="age != null">
            AND age = #{age}
        if>
    where>
select>

对比直接使用WHERE则需要手动添加逻辑连接符(如AND、OR)和条件语句,对于首个条件需要额外注意不要添加不必要的连接符。

<select id="findUsers" parameterType="map" resultType="User">
    SELECT * FROM users
    WHERE
        <if test="username != null">
            AND username = #{username}
        if>
        <if test="age != null">
            AND age = #{age}
        if>
select>

功能测试

注意token令牌过期问题需要使用接口登录获取新的token并设置全局变量
苍穹外卖学习Day2_第19张图片

代码完善

问题:日期格式不规范
苍穹外卖学习Day2_第20张图片
解决方案:
在这里插入图片描述
其中方式一仅对当前注解的变量有效,以后用到日期格式时需要重新添加。推荐使用第二种方式。
方法二,在WebMvcConfiguration配置类中重写父类

    /**
     * 扩展Spring MVC框架的消息转换器
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器..");
        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器,可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转换器加入容器中
        converters.add(0,converter);
    }

修改成功
苍穹外卖学习Day2_第21张图片

启用禁用员工账号

需求分析和设计

苍穹外卖学习Day2_第22张图片
业务规则:

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

接口文档:
苍穹外卖学习Day2_第23张图片

代码开发

在启用以及禁用过程中,当用户在浏览器界面点击启用禁用按钮时,参数可以将status值由1变0,由0变1,大概率是通过前端的JavaScript 的功能逻辑实现的,后期查看前端代码再解决。
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();
    }

@PathVariable以及前面@RequestBody 两个注解异同点总结

  • @PathVariable 主要用于从 URI 路径中提取变量值,适用于处理 RESTful 风格的请求。

  • @RequestBody 主要用于将请求体中的数据映射到方法的参数上,适用于处理 POST、PUT 等请求,接收客户端JSON 数据传递的数据。
    Service实现类

    /**
     * 启用禁用员工账号
     * @param status
     * @param id
     */
    @Override
    public void startOrStop(Integer status, Long id) {
        //update employee set staus= ? where id= ?
        Employee employee = new Employee();
        employee.setStatus(status);
        employee.setId(id);
        employeeMapper.update(employee);
    }

Mapper中的XML
因为只需要改status值即可,其实可以只写那一句status的标签但为了后续功能开发方便代码复用,所以全部判断并更新一遍。

   <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>
  • id=“update”:这是更新操作的唯一标识符,用于在 Java 代码中调用这个更新操作时引用该操作。
  • parameterType=“Employee”:指定了传递给 SQL 语句的参数类型为Employee。表示你可以在这个更新操作中使用Employee 类型的对象来传递参数。

在where中#{id} 中的 id 是指 Employee 对象中的属性,表示通过参数传递进来的 Employee 对象中的 id属性的值。具体的传递过程是在调用这个更新操作的 Java 代码中,通过传递一个包含 id 属性的 Employee 对象,将 id的值传递给 SQL 语句。

功能测试

苍穹外卖学习Day2_第24张图片
苍穹外卖学习Day2_第25张图片

编辑员工

需求分析

苍穹外卖学习Day2_第26张图片
苍穹外卖学习Day2_第27张图片

代码开发

根据id查询用户信息
此接口设计data中信息太多,实际上要根据id查询并回显用户信息仅用EmployeeDTO即可,不需要使用Employee可能还可以防止数据泄露提高安全性。
Controller层

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

Service实现层

    @Override
    public EmployeeDTO getById(Long id) {
        EmployeeDTO employeeDTO=employeeMapper.getById(id);
        return employeeDTO;
    }

Mapper层

    @Select("select * from employee where id = #{id}")
    EmployeeDTO getById(Long id);

编辑员工信息
Controller层

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

Servcie层

    /**
     * 编辑员工信息
     * @param employeeDTO
     */
    @Override
    public void update(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        //属性拷贝将DTO的属性赋值给employee对象
        BeanUtils.copyProperties(employeeDTO, employee);
        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(BaseContext.getCurrentId());
        employeeMapper.update(employee);
    }

导入分类模块功能代码

需求分析设计

苍穹外卖学习Day2_第28张图片
苍穹外卖学习Day2_第29张图片
剩余按照项目提供的代码导入。

你可能感兴趣的:(Java,学习,java,spring,boot,mybatis)