基于SpringBoot和MyBatisPlus实现的代码插件

news2024/11/16 13:39:30

1. 为什么自己开发插件

      目前市面上基于Mybatis或MybatisPlus的代码生成器或插件有很多,本人前几年也开发了一款:基于SpringBoot微服务代码自动生成插件。之前的开发的这款插件底层使用的持久层框架是通用Mapper,不是现在主流的MyBatisPlus,而且只支持mysql数据库,加上多年没有维护更新了,已经不适用于当前企业的开发需求了。

​      本人对市面上主流的基于MyBatis或MyBatisPlus插件使用后发现,这些插件生成的所有代码都只能对单表进行增删改查操作,如果需要同时对主从表进行增删改查就必须自己手写代码,而现实开发中,同时对主从表进行增删改查的需求是很常见的,这不得不使得开发人员需要花费大量的时间来编写同时对主从表进行增删改查的代码,严重的影响了开发进度和降低了开发效率。因此本人决定自己开发一款基于SpringBootMyBatisPlus的代码生成器,要实现三个目标:

  1. 不仅要实现单表的增删改查,还要支持同时对主从表的增删改查
  2. 开发人员只需要把表结构设计好,通过代码生成器生成代码后无需做任何修改就可以让前端进行接口联调。
  3. 至少减少开发人员90%的代码量。

目前插件已经开发完成并在公司多个项目中使用了,以上三个目标也得实现,下面就给介绍下这款代码生成插件的具体功能和使用方式。

2. 插件功能说明

  • 自动生成实体类:并配置好主从表的关系(如果有主从表)
  • 自动生成Mapper接口和对应的xml文件
  • 自动生成IBaseService接口文件:包含多个增删改查的方法以及多个供开发者根据需求进行扩展的方法
  • 自动生成业务层类:实现了IBaseService接口
  • 自动生成控制器类:包含了多个接口供前端调用对表进行增删改查操作
  • 自动生成SpringBoot工程启动类
  • 自动生成pom.xml文件:文件中包含了项目运行需要使用的依赖

3. 插件使用演示

  • 选择项目工程的任意文件夹右键

在这里插入图片描述

  • 点击插件名称后弹框如下图
    在这里插入图片描述
  • 选择表(可选)
    选择数据库厂商,填写数据库配置信息,选择要生成代码的表(这一步可以省略,如果不选择表则表示对数据库所有的表进行代码生成),选择好表之后直接点关闭按钮即可。
    在这里插入图片描述
  • 配置主从表关系
    重要:如果表与表之间有主从关联,需要按下图方式进行配置,否则无法同时进行主从表的增删改查操作。
    可以配置多组主从表关系,点击添加就会将选择好的信息移动到文本输入框显示,如果选择错了,可以手动编辑文本输入框,删除选错的主从表关系,多个主从表关系之间使用的是英文分号分割,配置好之后点确定按钮关闭配置主从表对话框即可。
    在这里插入图片描述
  • 继续填写剩下的信息
    最后点击确定按钮即可根据配置自动生成代码并保存到指定的目录下。
    在这里插入图片描述

4. 生成代码概述

4.1 表关系说明

先说明下上一步选择的四张表的关系:

task:任务表
task_user:任务用户表
task_stage:任务阶段表
task_scene:任务场景表
一个任务可以下发给多个用户,因此task表和task_user表关系是:一对多
一个任务有多个阶段,因此task表和task_stage表关系是:一对多
一个阶段有多个场景,因此task_stage表和task_scene表关系是:一对多
总结:一个任务分为多个阶段,每个阶段有多个场景,每个任务可以分给多个任务去完成
4.2 实体类包

选择的四个表对应的四个实体类在这里插入图片描述

4.4.1 Task类
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("task")
public class Task implements Serializable{

	@ApiModelProperty(value = "主键")
	@TableId(value = "id", type = IdType.ASSIGN_ID)
	private String id;

	@ApiModelProperty(value = "任务名称")
	@TableField("name")
	private String name;

     // 省略多个字段.....
	
     // 下面两个成员变量就是根据配置的表关系额外生成的
	@ApiModelProperty(value = "与子表:task_stage 关系:一对多")
	@TableField(exist = false)
	@ChildTable(childClass = TaskStage.class, foreignKey = "task_id")
	private List<TaskStage> taskStageList;

	@ApiModelProperty(value = "与子表:task_user 关系:一对多")
	@TableField(exist = false)
	@ChildTable(childClass = TaskUser.class, foreignKey = "task_id")
	private List<TaskUser> taskUserList;
}
4.4.2 TaskStage类
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("task_stage")
public class TaskStage implements Serializable{

	@ApiModelProperty(value = "主键")
	@TableId(value = "id", type = IdType.ASSIGN_ID)
	private String id;

	@ApiModelProperty(value = "阶段名称")
	@TableField("name")
	private String name;

  // 省略多个字段.....
	
  // 下面成员变量就是根据配置的表关系额外生成的
	@ApiModelProperty(value = "与子表:task_scene 关系:一对多")
	@TableField(exist = false)
	@ChildTable(childClass = TaskScene.class, foreignKey = "task_stage_id")
	private List<TaskScene> taskSceneList;
}
4.4.3 TaskUser类
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("task_user")
public class TaskUser implements Serializable{

	@ApiModelProperty(value = "培训任务ID")
	@TableField("task_id")
	private String taskId;
  
	@ApiModelProperty(value = "学员名称")
	@TableField("user_name")
	private String userName;
  
    // 省略多个字段.....
}
4.4.4 TaskScene类
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("task_scene")
public class TaskScene implements Serializable{

	@ApiModelProperty(value = "主键")
	@TableId(value = "id", type = IdType.ASSIGN_ID)
	private String id;
  
  @ApiModelProperty(value = "场景名称")
	@TableField("name")
	private String name;
    // 省略多个字段.....
  
	@ApiModelProperty(value = "关联阶段表主键")
	@TableField("task_stage_id")
	private String taskStageId;
}
4.3 Mapper接口包

在这里插入图片描述

4.4 Service包

在这里插入图片描述

4.5 Controller包

在这里插入图片描述

4.6 其他

在这里插入图片描述

5. 接口使用演示

在每个控制器中都生成了如下几个接口,这里以Task表对应的控制器来演示说明


@Api(tags = "task表前端控制器")
@RestController
@RequestMapping("/task")
public class TaskController {

    @Autowired
    private TaskService taskService;

    @ApiOperation(value = "查询 task 表所有记录-不分页")
    @PostMapping(value = "/findAll" )
    public R findAll(){
        return R.ok(taskService.findByCondition(null));
    }

    @ApiOperation(value = "根据条件分页查询 task 表记录")
    @PostMapping(value = "/findByCondition" )
    public R findByCondition(@RequestBody(required = false) TaskDTO taskDTO){
        return R.ok(taskService.findByCondition(taskDTO));
    }

    @ApiOperation(value = "根据id删除 task 表记录")
    @ApiImplicitParam(name = "id", value = "主键ID", required = true)
    @GetMapping(value = "/deleteById" )
    public R deleteById(@RequestParam(value = "id") String id){
        return R.ok(taskService.deleteById(id));
    }

    @ApiOperation(value = "新增或修改 task 表记录")
    @PostMapping(value="/saveOfUpdate")
    public R saveOfUpdate(@RequestBody Task task){
        return R.ok(taskService.saveOfUpdate(task));
    }

    @ApiOperation(value = "根据id查询 task 表详情")
    @ApiImplicitParam(name = "id", value = "主键ID", required = true)
    @GetMapping("/findById")
    public R findById(@RequestParam(value = "id") String id){
        return R.ok(taskService.findById(id));
    }
}
5.1 新增或更新任务
5.1.1 对应控制器方法
@ApiOperation(value = "新增或修改 task 表记录")
@PostMapping(value="/saveOfUpdate")
public R saveOfUpdate(@RequestBody Task task){
    return R.ok(taskService.saveOfUpdate(task));
}
5.1.2 无id则代表新增

在这里插入图片描述
​ 执行请求之后,会在任务表task中添加一条记录,在阶段表task_stage中添加两条记录,每个阶段在场景表task_scene中有两条记录,在task_user表中有两条记录。

5.1.3 有id则代表更新在这里插入图片描述

执行请求之后,会更新主表和与之关联的所有从表的信息。

5.2 删除任务
5.2.1 对应控制器的方法
@ApiOperation(value = "根据id删除 task 表记录")
@ApiImplicitParam(name = "id", value = "主键ID", required = true)
@GetMapping(value = "/deleteById" )
public R deleteById(@RequestParam(value = "id") String id){
    return R.ok(taskService.deleteById(id));
}
5.2.2 通过PostMan调用接口在这里插入图片描述

执行请求后会根据id删除task表对应的记录,同时也会删除从表task_stage,task_user与之关联的记录,task_stage表关联的从表task_scene中相关联的记录也会删除。

5.3 查询任务详情
5.3.1 对应控制器的方法
@ApiOperation(value = "根据id查询 task 表详情")
@ApiImplicitParam(name = "id", value = "主键ID", required = true)
@GetMapping("/findById")
public R findById(@RequestParam(value = "id") String id){
    return R.ok(taskService.findById(id));
}
5.3.2 通过PostMan调用接口

在这里插入图片描述
执行请求后会根据id查询task表的对应记录,与之关联的所有的从表记录也会查询出来,结果如下图:
在这里插入图片描述

5.4 查询所有任务
5.4.1 对应控制器的方法
@ApiOperation(value = "查询 task 表所有记录-不分页")
@PostMapping(value = "/findAll" )
public R findAll(){
    return R.ok(taskService.findByCondition(null));
}
5.4.2 通过PostMan调用接口在这里插入图片描述

该接口是不带条件不分页的查询表中的所有记录。

5.5 分页查询任务列表
5.5.1 对应控制器的方法
@ApiOperation(value = "根据条件分页查询 task 表记录")
@PostMapping(value = "/findByCondition" )
public R findByCondition(@RequestBody(required = false) TaskDTO taskDTO){
    return R.ok(taskService.findByCondition(taskDTO));
}
5.5.2 参数TaskDTO类概述
  • 每个表都会生成一个对应DTO类,用来封装分页参数和查询条件的,默认生成的DTO类如下所示:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class TaskDTO implements Serializable{
    /**
     * 分页查询页号
     */
    private Integer pageNo = 1;

    /**
     * 分页查询页大小
     */
    private Integer pageSize = 20;
}
5.5.3 通过PostMan调用接口

在这里插入图片描述
执行请求之后就能分页查询表记录了,返回结果如下图:
在这里插入图片描述

5.6 分页带条件查询任务列表
@ApiOperation(value = "根据条件分页查询 task 表记录")
@PostMapping(value = "/findByCondition" )
public R findByCondition(@RequestBody(required = false) TaskDTO taskDTO){
    return R.ok(taskService.findByCondition(taskDTO));
}

与上一个接口是同一个接口,只需要在dto类中配置下条件信息即可,比如查询列表时要根据任务名称过滤列表数据,只需要在dto中添加一个字段并使用自定义注解@Condition配置下就可以,如下图所示:
在这里插入图片描述
如果需要有更多的过滤条件,继续添加字段即可,不需要修改自动生成的代码就实现了带条件分页查询列表了。

5.7 接口使用小结

以上演示的接口都是插件自动生成就有的,不管是单表和有主从关系的表都可以使用。不需要任何修改就能让前端调用了。如果执行增删改查时需要对请求参数或查询结果做特殊处理,比如在新增数据时需要对请求参数进行校验,校验不通过则会直接响应给前端,可以重写:boolean beforeSaveOfUpdate(T t) 方法。还有很多方法可以让使用者根据业务需求决定是否需要重写。如果没有特殊需求的,完全不需要写代码就可以实现增删改查接口的开发。

6. 写在最后的话在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1479760.html

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

相关文章

【探索AI】十二 深度学习之第2周:深度神经网络(一)深度神经网络的结构与设计

第2周&#xff1a;深度神经网络 将从以下几个部分开始学习&#xff0c;第1周的概述有需要详细讲解的的同学自行百度&#xff1b; 深度神经网络的结构与设计 深度学习的参数初始化策略 过拟合与正则化技术 批标准化与Dropout 实践&#xff1a;使用深度学习框架构建简单的深度神…

奇安信发布《2024人工智能安全报告》,AI深度伪造欺诈激增30倍

2024年2月29日&#xff0c;奇安信集团对外发布《2024人工智能安全报告》&#xff08;以下简称《报告》&#xff09;。《报告》认为&#xff0c;人工智能技术的恶意使用将快速增长&#xff0c;在政治安全、网络安全、物理安全和军事安全等方面构成严重威胁。 《报告》揭示了基于…

为什么电池对eVTOL来说是一个问题

Electric Power Systems首席技术官Michael Armstrong表示&#xff0c;电动垂直起降&#xff08;eVTOL&#xff09;飞机面临着独特的电池挑战&#xff0c;这将要求开发人员改变他们对电池系统和电动汽车设计的看法。 阿姆斯特朗说&#xff1a;“如果我们研究先进空中交通、第23部…

iPhone上备忘录分享到微信 苹果手机备忘录微信分享

在繁忙的生活中&#xff0c;iPhone的备忘录功能一直是我记录琐事、灵感和待办事项的得力助手。然而&#xff0c;每当我精心编辑好一段内容&#xff0c;想要将其分享给微信好友或发到朋友圈时&#xff0c;却常常遭遇分享难题。那种无法将精彩瞬间轻松分享给朋友的无奈&#xff0…

易货模式微信小程序的可行性分析

随着移动互联网技术的快速发展&#xff0c;微信小程序作为一种轻量级的应用形态&#xff0c;已经成为众多创业者和服务提供者关注的焦点。微信小程序以其便捷的使用体验、较低的开发成本和广泛的用户基础&#xff0c;成为了各类业务模式的创新平台。在这样的背景下&#xff0c;…

如何将java程序打包成可执行文件

问题提出 当你写了一个很炫酷的java小游戏&#xff0c;你迫不及待想给朋友分享。然而&#xff0c;你发给朋友之后&#xff0c;他却表示无法执行。因为我们无法保证其他人的电脑上已经安装了java运行环境。 所以&#xff0c;我们有哪些方法把我们的炫酷代码分享给朋友呢&#…

基于SSM SpringBoot vue服装物流管理系统

基于SSM SpringBoot vue服装物流管理系统 系统功能 首页 图片轮播 人个中心 登录注册 后台管理: 登录注册 个人中心 货物信息管理 货物入库管理 订单信息管理 商品出库管理 快递追踪管理 用户管理 供应商信息管理 盘点信息管理 管理员管理 开发环境和技术 开发语言&#xf…

纯css实现-让字符串在文字少时显示为居中对齐,而在文字多时显示为左对齐

纯css实现-让字符串在文字少时显示为居中对齐&#xff0c;而在文字多时显示为左对齐 使用flex实现 思路 容器样式&#xff08;.container&#xff09;: Flex容器的BFC性质使得其内部的子元素&#xff08;.text-box&#xff09;在水平方向上能够居中&#xff0c;通过justify-c…

Python web框架fastapi数据库操作ORM(一)

文章目录 Fastapi ORM操作1、创建模型2、创建数据库连接配置文件3、启动项目4、根据模型类创建数据库表1. 初始化配置&#xff0c;只需要使用一次2. 初始化数据库&#xff0c;一般情况下只用一次3. 更新模型并进行迁移4. 重新执行迁移&#xff0c;写入数据库5. 回到上一个版本6…

RFID射频识别技术的优势

目前RFID在金融支付、物流、零售、制造业、医疗、身份识别、防伪、资产管理、交通、食品、动物识别、汽车、等行业都已经实现不同程度的商业化使用。未来&#xff0c;RFID技术有不可替代的六大优势&#xff0c;也保证了物联网的万物互联的有序发展! 1、无需可视&#xff0c;在无…

第零章_计算机导论

0.1 计算机&#xff1a;辅助人脑的好工具 所谓的计算机就是一种计算器&#xff0c;而计算器其实是:『接受用户输入指令与数据&#xff0c;经由中央处理器的数学与逻辑单元运算处理后&#xff0c;以产生或储存成有用的信息』。因此&#xff0c;只要有输入设备(不管是键盘还是触摸…

【软考高项】【计算专题】- 5 - 进度类 - 横道图/甘特图

一、知识点 1、基本定义 甘特图(Gantt chart )又称为横道图、条状图(Bar chart)&#xff0c;通过条状图来显示项目各活动的进 度情况。以提出者亨利劳伦斯甘特( Henry Laurence Gantt)先生的名字命名。 目前许多文档工具都可以画甘特图。 &#xff08;1&#xff09;我的举例 …

PSO-CNN-LSTM多输入回归预测|粒子群算法优化的卷积-长短期神经网络回归预测(Matlab)——附代码数据

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序数据分享下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台…

javaWeb个人学习04

AOP核心概念: 连接点: JoinPoint, 可以被AOP控制的方法 通知: Advice 指哪些重复的逻辑&#xff0c;也就是共性功能(最终体现为一个方法) 切入点: PointCut, 匹配连接点的条件&#xff0c;通知仅会在切入点方法执行时被应用 目标对象: Target, 通知所应用的对象 通知类…

内网穿透 nas/树莓派+ipv4服务器 (ipv6)

nas 1.有个服务器 2.有个nas https://github.com/snail007/goproxy/blob/master/README_ZH.md https://github.com/snail007/proxy_admin_free/blob/master/README_ZH.md 2个官网一个是程序&#xff0c;一个是网站 手册 https://snail007.host900.com/goproxy/manual/zh/#/?i…

JavaScript DOM操作笔记记录回忆总结

一、什么是DOM&#xff1f; 1、通过 HTML DOM&#xff0c;可访问 JavaScript HTML 文档的所有元素。 2、当网页被加载时&#xff0c;浏览器会创建页面的文档对象模型&#xff08;Document Object Model&#xff09; 二、操作DOM 1、在操作DOM之前&#xff0c;我们需要先获取到…

DolphinScheduler——奇富科技的调度实践

目录 一、技术架构 二、业务挑战 2.1 调度任务量大 2.2 运维复杂 2.3 SLA要求高 三、调度优化实践 3.1 重复调度 3.2 漏调度 3.3 Worker服务卡死 3.4 任务重复运行 四、服务监控 4.1 方法耗时监控 4.2 任务调度链路监控 五、用户收益 原文大佬的这篇调度系统案例…

图像分割 - 查找图像的轮廓(cv2.findContours函数)

1、前言 轮廓,是指图像中或者物体的外边缘线条。在简单的几何图形中,图形的轮廓是由平滑的线条构成,容易被识别。但不规则的图形或者生活中常见的物体轮廓复杂,识别起来比较困难 2、findContours函数 这里先介绍函数的参数,具体的含义会在下面实验中阐述 opencv 提供的轮…

(正规api接口代发布权限)短视频账号矩阵系统实现开发--技术全自动化saas营销链路生态

短视频账号矩阵系统实现开发--技术全自动化saas营销链路生态源头开发&#xff08;本篇禁止抄袭复刻&#xff09; 一、短视频矩阵系统开发者架构 云罗短视频矩阵系统saas化系统&#xff0c;开发层将在CAP原则基础上使用分布式架构,对此网站的整体架构采用了基于B/S三层架构模式…

计算机网络——21拥塞控制原理

拥塞控制原理 概述 拥塞 非正式的定义&#xff1a;“太多的数据需要网络传输&#xff0c;超过了网络的处理能力”与流量控制不同拥塞的表现 分组丢失&#xff08;路由器缓冲区溢出&#xff09;分组经历比较长时间的延迟&#xff08;在路由器的队列中排队&#xff09; 网络中…