Dayu Toolkit之代码自动生成插件

简介: 在2B场景下,相当数量中小项目的领域模型是多字段的单表(实体)增删改查。对后端研发同学,实现这样的业务逻辑,粗略地看,无非下面几个基本操作。• 创建数据库表,并添加业务字段。• 撰写Java实体类DO,添加对应的字段。• 撰写Java数据操作类,DAO,撰写相关方法。• 撰写Service类,增加对相关实体的CRUD操作。• 如果是Web应用,撰写Controller类,暴露相关的REST API。也就是说,在定义了数据库表结构以后,上述都是一些机械化和模板化的重复操作。因此我们开发了基于Intellij的CRUD代码自动生成插件。

背景

2B场景下,相当数量中小项目的领域模型是多字段的单表(实体)增删改查。对后端研发同学,实现这样的业务逻辑,粗略地看,无非下面几个基本操作。

  • 创建数据库表,并添加业务字段。
  • 撰写Java实体类DO,添加对应的字段。
  • 撰写Java数据操作类,DAO,撰写相关方法。
  • 撰写Service类,增加对相关实体的CRUD操作。
  • 如果是Web应用,撰写Controller类,暴露相关的REST      API

也就是说,在定义了数据库表结构以后,上述都是一些机械化和模板化的重复操作。因此我们开发了基于IntellijCRUD代码自动生成插件。

主要功能

主要功能非常简单,就是在IDE中连接数据库后,选择数据库表后,根据表结构生成:

  • Java实体类
  • Mybatis或者Mybatis plus风格的Mapper
  • 我们推荐使用Mybatis       plus,因为它极大地降低了代码的复杂度。当然联表查询情况下,用户依然可以使用Mybatis撰写SQL语句。
  • 对应的mapper      xml文件,如果有的话
  • 对应的ServiceController
  • 各个模块的单元测试文件
  • 根据选择的表在resources/schema.sql中目录生成建表语句

对应文件生成的风格根据当前目录结构自动判别,支持两种风格:

  1. dayu-boot六边形脚手架(dayu-boot脚手架是阿里云GTS开发的面向交付场景设计的后端Java脚手架)
  2. 分层结构(controller/service/dao)脚手架

快速开始

添加插件库地址

该地址暂时不对外透出,请联系李晨(ruli.lc@alibaba-inc.com)获取

image.png

安装“code-generation”插件

image.png我们下面用一个例子来说明在大禹脚手架的场景下,如何使用插件来生成代码。
假设现在我们有一张名为employee(员工)的表,字段如下:

字段名

意义

类型

id

bigint

主键

name

varchar

姓名

age

int

年龄

同时我们通过大禹交付平台,使用大禹脚手架初始化完成一份基础代码。

生成代码

生成代码的方式非常简单。在项目目录右击或在代码空白处右击,选中code-generation -> MySQL生成后,插件会根据当前项目的代码结构识别脚手架类型。image.png点击“Next”,选择当前保存的数据库连接,或者新建一个连接,测试其连通性。如果本地可以连接数据库,那么选择连接以后,会展现当前数据库实例中的所有库。

image.png选择想展示的库以后,点击“Next”,展示所有表信息。这里我们既可以选择一个表,生成该表对应的Java实体及其相关的代码,也可以选择多个表,生成多套代码。这里我们选择刚刚创建的employee表。

image.png

注意在六边形脚手架中,我们按照规范,只会生产MybatisPlus风格的mapper类。这样我们的employee相关的代码就生成完毕了。我们来看看插件都帮我们生产了什么。下面列举主要的几个核心文件。

模型实体类

一个和表结构相关的Java实体类。如果建表的时候提供了comment信息,相应的注释上会填充相关信息。

@Data
public class Employee {
 
         
/**
*
*/
private Long id;
 
         
/**
*
*/
private String name;
 
         
/**
*
*/
private Integer age;
 
         
}

数据库实体类

也就是我们通常说的“DO”

@Data
@TableName("employee")
public class EmployeeEntity {
 
         
/**
*
*/
@TableId
@TableField("id")
private Long id;
 
         
/**
*
*/
@TableField("name")
private String name;
 
         
/**
*
*/
@TableField("age")
private Integer age;
 
         
}

DAO相关的类

dayu-boot脚手架的场景下,一个Repository实现类和一个MybatisPlus风格的Mapper接口类。

@AllArgsConstructor
public class EmployeeMyBatisRepository implements EmployeeRepository  {
 
         
private EmployeeEntityMapper  employeeEntityMapper;
 
         
@Override
public Employee findById(Long id) {
EmployeeEntity employeeEntity = employeeEntityMapper.selectById(id);
if (employeeEntity != null) {
Employee employee = new Employee();
BeanUtils.copyProperties(employeeEntity, employee);
return employee;
}
return null;
}
//省略其他方法
}

Service层的操作类

@AllArgsConstructor
public class EmployeeDomainService {
 
         
private EmployeeRepository employeeRepository;
 
         
public Employee createEmployee(Employee employee) {
Employee newEmployee = employeeRepository.save(employee);
return newEmployee;
}
 
         
public Employee findEmployeeById(Long id) {
return employeeRepository.findById(id);
}
 
         
public Employee updateEmployee(Employee employee) {
return employeeRepository.update(employee);
}
 
         
public Boolean deleteEmployeeById(Long id) {
return employeeRepository.delete(id);
}
 
         
public PageResult searchByPage(EmployeeSearchByPage employeeSearchByPage) {
return employeeRepository.findByPage(employeeSearchByPage);
}
 
         
}

Controller

生成的Controller中相关的REST API

@RestController
@RequestMapping("/employee")
public class EmployeeController implements EmployeeAPIHttp {
 
         
@Autowired
private EmployeeAppService employeeAppService;
 
         
@Override
public ResultResponse<EmployeeDTO> createEmployee(EmployeeDTO employeeDTO) {
return employeeAppService.createEmployee(employeeDTO);
}
 
         
@Override
public ResultResponse<EmployeeDTO> findEmployeeById(Long id) {
return employeeAppService.findEmployeeById(id);
}
 
         
@Override
public ResultResponse<EmployeeDTO> updateEmployee(EmployeeDTO employeeDTO) {
return employeeAppService.updateEmployee(employeeDTO);
}
 
         
@Override
public ResultResponse<Boolean> deleteEmployeeById(Long id) {
return employeeAppService.deleteEmployeeById(id);
}
 
         
 
         
@Override
public ResultResponse<ApiPageResult> searchByPage(EmployeeSearch employeeSearch) {
return employeeAppService.searchByPage(employeeSearch);
}
 
         
}

最后插件也在每一个module中生成了相关的单测方法,我们现在举一个在domain层的单测类为例。

单元测试

@Test
public void testEmployee() {
Employee employee = new Employee ();
Employee newEmployee  = employeeDomainService.createEmployee(employee);
assertNotNull(newEmployee .getId());
 
         
Employee  searchEmployee  = employeeDomainService.findEmployeeById(newEmployee.getId());
assertEquals(newEmployee.getId(),searchEmployee .getId());
 
         
Employee  updateEmployee  = employeeDomainService.updateEmployee (searchEmployee );
assertEquals(searchEmployee .getId(),updateEmployee .getId());
 
         
EmployeeSearchByPage employeeSearchByPage = new EmployeeSearchByPage();
employeeSearchByPage.setPageSize(5);
employeeSearchByPage.setPageNum(1);
PageResult<Employee > pageResult = employeeDomainService.searchByPage(employeeSearchByPage);
assertEquals(pageResult.getSize(),Long.valueOf(employeeSearchByPage.getPageSize()));
assertNotNull(pageResult.getList());
 
         
Boolean aBoolean = employeeDomainService.deleteEmployeeById(searchEmployee.getId());
assertTrue(aBoolean);
 
         
Employee  searchNewEmployee  = employeeDomainService.findEmployeeById(searchEmployee.getId());
assertNull(searchNewEmployee );
 
         
}

基本设置是:

  • 创建实体
  • 通过id查询实体,验证创建成功
  • 更新实体,验证更新成功
  • 按条件查询实体

非大禹脚手架的分层结构也非常类似,不再赘述。

未来规划

我们希望推出一系列面向交付的研发插件套件,能涵盖从表结构设计,业务代码生成,单元测试,前端代码生成,前后端联调等场景,从而提高交付场景下的研发效能。它们是我们交付场景下的“Dayu Toolkit”

目录
相关文章
|
缓存 JavaScript Cloud Native
阿里云发布 Spring Boot 新脚手架,真香
本文,围绕 spring initializr 框架,以 start.spring.io 为例,全面的给大家介绍如何使用和扩展这个框架,以及背后的运行原理。
56725 1
阿里云发布 Spring Boot 新脚手架,真香
|
运维 数据可视化 网络协议
Docker可视化工具Portainer的安装和使用
Docker可视化工具Portainer的安装和使用
17110 1
Docker可视化工具Portainer的安装和使用
|
数据可视化 IDE 安全
云巧-让开发更简单,更高效,更方便
近年来,快速迭代的新需求将引导企业改变其开发方式,进而转向使用支持快速、安全和高效的技术架构,组装式应用便成为了企业重要的战略技术趋势。组装式应用引入模块化的理念,使得各企业可以更敏捷、更有效地复用能力模块,提高商业的韧性和效率。云巧平台应运而生,能极大的改善开发环境,节省开发工作量,让开发更简单,更高效,更方便。
2212 0
|
2月前
|
Ubuntu 应用服务中间件 Linux
通过Certbot自动申请更新HTTPS网站的SSL证书
本文介绍了如何通过 Certbot 自动申请并更新 HTTPS 网站的 SSL 证书,配合 Crontab 实现自动续签,解决云服务商免费证书仅限 3 个月有效期的问题,适用于 CentOS、Debian、Ubuntu 系统,支持 Nginx 和 Apache 服务器。
260 6
|
11月前
|
消息中间件 存储 Java
吃透 RocketMQ 消息中间件,看这篇就够了!
本文详细介绍 RocketMQ 的五大要点、核心特性及应用场景,涵盖高并发业务场景下的消息中间件关键知识点。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
吃透 RocketMQ 消息中间件,看这篇就够了!
|
前端开发 JavaScript Java
SpringBoot项目部署打包好的React、Vue项目刷新报错404
本文讨论了在SpringBoot项目中部署React或Vue打包好的前端项目时,刷新页面导致404错误的问题,并提供了两种解决方案:一是在SpringBoot启动类中配置错误页面重定向到index.html,二是将前端路由改为hash模式以避免刷新问题。
891 1
|
7月前
|
人工智能 Java 程序员
通义灵码 2.0 | AI程序员 荣耀登场
通义灵码2.0引入了AI程序员,具备多文件代码修改和使用工具的能力,可帮助开发者完成需求实现、问题解决、单元测试用例生成等任务。相比1.0版本,2.0在代码生成速度、准确度及自然语言理解方面有显著提升,支持更多上下文类型如#file、#codeChanges等,便于灵活提问与代码审查。本文通过实际操作展示了AI程序员在功能开发、跨语言编程等方面的应用,体验良好;但在单元测试环节遇到环境检查问题未能解决,希望后续能提供更详细的修复文档。总体而言,AI程序员大幅提升了开发效率,尤其在新功能迭代和错误排查方面表现出色,但生成的代码风格有时需人工调整以适应现有项目结构。
|
12月前
|
Ubuntu Linux 网络安全
Docker&Docker Compose安装(离线+在线)
Docker&Docker Compose安装(离线+在线)
13835 1
|
消息中间件 负载均衡 算法
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
517 2
|
安全 JavaScript 前端开发
Wasmer 3.0 发布,可在浏览器外运行 WebAssembly
Wasmer 3.0 发布,可在浏览器外运行 WebAssembly
237 2