员工管理、API文档

员工管理、API文档

API文档Knife4j

相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前端调用后端,还是后端调用后端,都期望有一个好的接口文档。但是这个接口文档对于程序员来说,就跟注释一样,经常会抱怨别人写的代码没有写注释,然而自己写起代码起来,最讨厌的,也是写注释。所以仅仅只通过强制来规范大家是不够的,随着时间推移,版本迭代,接口文档往往很容易就跟不上代码了。

现在的项目很多是敏捷开发,需求变化也快,导致接口文档不断变化。使用静态接口文档不利于更新,推荐是使用动态API文档(html网页格式)。

动态API文档可以由前端人员编写(在线工具),也可以后端“编写”(生成)。

API文档的技术,流行:swagger、spring doc(OpenAPI3)、Knife4j。

Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案,Knife4j是一个集Swagger2 和 OpenAPI3,为一体的增强解决方案

官网:https://doc.xiaominfo.com/

下面要在后端项目中添加Knife4j:

https://doc.xiaominfo.com/docs/quick-start

前提条件:

在这里插入图片描述

员工管理、API文档

API文档Knife4j

相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前端调用后端,还是后端调用后端,都期望有一个好的接口文档。但是这个接口文档对于程序员来说,就跟注释一样,经常会抱怨别人写的代码没有写注释,然而自己写起代码起来,最讨厌的,也是写注释。所以仅仅只通过强制来规范大家是不够的,随着时间推移,版本迭代,接口文档往往很容易就跟不上代码了。

现在的项目很多是敏捷开发,需求变化也快,导致接口文档不断变化。使用静态接口文档不利于更新,推荐是使用动态API文档(html网页格式)。

动态API文档可以由前端人员编写(在线工具),也可以后端“编写”(生成)。

API文档的技术,流行:swagger、spring doc(OpenAPI3)、Knife4j。

Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案,Knife4j是一个集Swagger2 和 OpenAPI3,为一体的增强解决方案

官网:https://doc.xiaominfo.com/

下面要在后端项目中添加Knife4j:

https://doc.xiaominfo.com/docs/quick-start

前提条件:

首先,引用Knife4j的starter,Maven坐标如下:

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.1.0</version>
</dependency>

引入之后,其余的配置,开发者即可完全参考springdoc-openapi的项目说明,Knife4j只提供了增强部分,如果要启用Knife4j的增强功能,可以在配置文件中进行开启

部分配置如下:

部分配置如下:

# springdoc-openapi项目配置
springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs
  group-configs:
    - group: 'default'
      paths-to-match: '/**'
      # 最重要:包扫描Controller
      packages-to-scan: cn.bobohost.market.web.controller
# knife4j的增强配置,不需要增强可以不配
knife4j:
  enable: true
  setting:
    language: zh_cn

注意:扫描的Controller的包!

访问文档:

通过http://localhost:8989/doc.html 访问

最后,使用OpenAPI3的规范注解,注释各个Spring的REST接口,示例代码如下:

package cn.bobohost.market.web.controller;

import cn.bobohost.market.common.pojo.ResultDto;
import cn.bobohost.market.common.pojo.ResultPageDto;
import cn.bobohost.market.pojo.Employee;
import cn.bobohost.market.service.EmployeeService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 员工操作的Controller
 */
//允许跨域
@CrossOrigin
@RestController
@RequestMapping("/emp")
@Tag(name = "员工管理")
public class EmployeeController {

    //注入service
    @Autowired
    private EmployeeService employeeService;


    /**
     * 查询员工列表
     * 注意:请求地址和方法必须符合接口文档;参数得能装进去
     * @param searchData
     * @return
     */
    @GetMapping("/getEmp")
    @Operation(summary = "分页条件查询员工列表")
    @Parameters({
            @Parameter(name = "currentPage",description = "当前页码",required = true,in = ParameterIn.QUERY),
            @Parameter(name = "pageSize",description = "每页最大记录数",required = true,in = ParameterIn.QUERY),
            @Parameter(name = "searchData",description = "查询的条件的数据",required = true,in= ParameterIn.QUERY)
    })
    public ResultDto getEmp( Employee searchData, int currentPage, int pageSize){

        //调用业务层查询分页数据
        Page page = employeeService.findEmployeeListPage(searchData, currentPage, pageSize);
        //分页的结果重新封装
        ResultPageDto resultPageDto = ResultPageDto.of(page.getTotal(), page.getRecords());

        return ResultDto.success("查询分页列表成功!",resultPageDto);

    }


}

重启服务,重新访问api文档

另外:API文档不但可以生成接口文档、查看接口api,还能测试用(暂时替代postman):

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/a2b1632853cc4dbbad35adba7819e5af.png

员工管理前端代码分析

分析前端相关代码,目标:让你可以随便改。

回顾:局部组件(先引入,然后用组件标签);全局组件(先引入,使用Vue.use使用)

内容:

自定义菜单

自定路由

自定义页面

页面调用

员工的添加

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

查看数据库:
在这里插入图片描述

前端测试:
在这里插入图片描述

后端代码

表现层:

    @PostMapping("/addEmp")
    @Operation(summary = "添加一个员工")
    public ResultDto addEmp(@RequestBody Employee employee){
        employeeService.saveEmployee(employee);

        return  ResultDto.success("保存员工成功!",null);

    }

业务层:

   /**
     * 保存一个员工
     * @param employee
     */
    void saveEmployee(Employee employee);
  @Override
    public void saveEmployee(Employee employee) {
        employeeMapper.insert(employee);
    }

路由的跳转

在这里插入图片描述

id的雪花算法

在这里插入图片描述

mysql内置的自增长主键不太适合实际业务:

只能保证同一张表的id不重复,不同表的id是会重复的—影响不是很大。

将来对数据库做分库集群的时候,如果还让mysql自己生成id,那么每一个mysql只管自己的id不重复,但整个集群的同一张表的id会重复。
在这里插入图片描述

解决方案:不要让mysql自己生成。用程序生成。

我们现在流行用分布式id生成策略:推特的一个算法:雪花算法。。原理自己看看

在这里插入图片描述

MyBatis plus 新版本默认使用雪花算法了

雪花算法(Snowflake Algorithm)是一种用于生成全局唯一的分布式ID的算法。它最初由Twitter开发,用于解决分布式系统中的ID生成问题。

雪花算法的核心思想是将一个64位的ID划分成多个部分,每个部分表示不同的信息。具体来说,一个雪花ID由以下几个部分组成:

  1. 时间戳(41位):使用毫秒级的时间戳,可以支持约69年的时间跨度。
  2. 工作节点ID(10位):用于标识不同的工作节点或机器,可以支持最多1024个节点。
  3. 序列号(12位):表示同一毫秒内生成的ID序列号,可以支持每个节点每毫秒产生最多4096个ID。

在分布式系统中,每个工作节点都需要一个唯一的节点ID。通过将时间戳、工作节点ID和序列号按照一定的规则组合起来,就可以生成全局唯一的ID。

使用雪花算法生成的ID具有一定的优势,包括全局唯一性、趋势递增、精确到毫秒、高性能等特点。它可以在分布式环境下快速生成唯一ID,并且不依赖于中心化的ID生成器。

然而,需要注意的是,雪花算法并不能保证绝对的有序性,因为它无法解决网络延迟等问题带来的时钟回拨或者时钟漂移。在实际使用中,需要根据具体场景和需求来评估雪花算法是否适合。

员工的修改

修改的业务都是俩动作:数据回显和数据更新

在这里插入图片描述

数据回显

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

数据回显,有两种方式:

  • 一种直接从页面获取。优点:效率高。缺点:如果数据库的数据发生了变化,则获取不到最新数据。
  • 一种是从数据库重新查询。优点:可以查看到最新的数据。缺点:效率低。—自己实现。

数据更新

更新数据的api可以和保存数据用一个。

后端如何区分是保存?还是更新?

根据id是否有值来区分:没值的是保存,有值的是更新。

后端代码:

修改conroller

    @PostMapping("/addEmp")
    @Operation(summary = "添加一个员工")
    public ResultDto addEmp(@RequestBody Employee employee){
        if(StringUtils.hasText(employee.getId())){
            //更新操作
            employeeService.updateEmployee(employee);
            return  ResultDto.success("修改员工成功!",null);
        }else{
            //保存操作
            employeeService.saveEmployee(employee);
            return  ResultDto.success("保存员工成功!",null);
        }
    }

业务层接口代码:

/**
     * 更新
     * @param employee
     */
    void updateEmployee(Employee employee);

业务层实现:

  @Override
    public void updateEmployee(Employee employee) {
        employeeMapper.updateById(employee);
    }

使用api文档来测试:

在这里插入图片描述

对接前端测试:

在这里插入图片描述

修改成功,刷新列表,隐藏修改框:
在这里插入图片描述

员工的删除

在这里插入图片描述

通常删除分为物理删除和逻辑删除。

  • 物理删除:将数据真正从数据库删除。—先实现。
  • 逻辑删除:更改了在数据库中的一个删除标识(deleted),但数据仍然存在数据库中。

物理删除员工:

前端:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后端代码:

表现层:

  @PostMapping("/deleteEmpById")
    @Operation(summary = "删除员工")
    public ResultDto deleteEmpById(@RequestBody String id){

        employeeService.deleteEmployeeById(id);
        return  ResultDto.success("删除员工成功!",null);
    }

业务层接口:

  /**
     * 删除员工
     * @param id
     */
    void deleteEmployeeById(String id);

业务层实现:

  @Override
    public void deleteEmployeeById(String id) {
        //物理删除
//        employeeMapper.deleteById(id);
        //逻辑删除--更新操作--将用户禁用
        Employee employee=new Employee();
        employee.setId(id);
        employee.setStatus("inactive");
        employeeMapper.updateById(employee);
    }

api测试
在这里插入图片描述

前端测试:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值