SpringCloud微服务实战——搭建企业级开发框架(三十一):自定义MybatisPlus代码生成器实现前后端代码自动生成
理想的情况下,代码生成可以节省很多重复且没有技术含量的工作量,并且代码生成可以按照统一的代码规范和格式来生成代码,给日常的代码开发提供很大的帮助。但是,代码生成也有其局限性,当牵涉到复杂的业务逻辑时,简单的代码生成功能无法解决。
目前市面上的代码生成器层出不穷,大多数的原理是基于已有的代码逻辑模板,按照一定的规则来生成CRUD代码。至于更为复杂的代码生成大家都在人工智能领域探索,目前基于代码训练的人工智能代码生成还在于提供代码补全功能方面,比如智能编程助手aiXcoder提供了常用IDE插件,在项目开发过程中,可以基于你项目的代码进行训练,编程时提供合适的代码提示。由微软、OpenAI、GitHub 三家联合打造的Copilot 也有异曲同工之妙,都是在项目开发中,提供优秀的代码自动补全功能从而可以提升工作效率。希望在不远的将来,我们可以实现复杂业务逻辑的代码也通过人工智能对大量代码的训练和分析来实现吧。
这里我们制作的代码生成器,是按照平时开发过程中的思考来设计,一般情况下我们的开发步骤是: 需求分析->数据建模->数据库设计->编写后台代码(增删改查)->编写前台代码(增删改查)->字段校验 ->业务逻辑完善->测试,所以我们希望代码生成器能够:
- 读取数据库表和字段
- 根据数据库字段生成实体类和CRUD方法
- 根据数据库字段生成前端操作页面
- 前端页面的展示方式可以根据需要配置(form表单、数据展示列表)
- 可以生成多表联合查询的代码
- 可以配置字段的校验规则
一、引入依赖的库
1、修改GitEgg-Platform项目中的gitegg-platform-bom工程的域名文件,这里使用mybatis-plus-generator目前最新版本3.5.1来自定义我们需要的代码生成器。
域名
<properties>
......
<!-- Mybatis Plus增强工具代码生成 -->
<域名域名ion>3.5.1</域名域名ion>
......
</properties>
<dependencymanagement>
<dependencies>
......
<!-- Mybatis Plus代码生成工具 -->
<dependency>
<groupid>域名idou</groupid>
<artifactid>mybatis-plus-generator</artifactid>
<version>${域名域名ion}</version>
</dependency>
......
</dependencies>
</dependencymanagement>
2、在GitEgg-Platform项目中新建gitegg-platform-code-generator工程,提供基本的自定义代码生成能力,以及定义一些常量。
域名常量类
package 域名域名域名tant;
import 域名;
/**
* @ClassName: GitEggCodeGeneratorConstant
* @Description: 常量类
* @author GitEgg
* @since 2021-10-12
*/
public class GitEggCodeGeneratorConstant {
/**
* CONFIG
*/
public static final String CONFIG = "config";
/**
* FIELDS
*/
public static final String FIELDS = "fields";
/**
* FORM_FIELDS
*/
public static final String FORM_FIELDS = "formFields";
/**
* BASE_ENTITY_FIELD_LIST
*/
public static final String BASE_ENTITY_FIELD_LIST = "baseEntityFieldList";
/**
* Author
*/
public static final String AUTHOR = "GitEgg";
/**
* JAVA_PATH
*/
public static final String JAVA_PATH = 域名rator + "src" + 域名rator + "main" + 域名rator + "java" + 域名rator;
/**
* RESOURCES_PATH
*/
public static final String RESOURCES_PATH = 域名rator + "src" + 域名rator + "main" + 域名rator + "resources" + 域名rator;
/**
* VUE_PATH
*/
public static final String VUE_PATH = 域名rator + "src" + 域名rator + "views" + 域名rator;
/**
* JS_PATH
*/
public static final String JS_PATH = 域名rator + "src" + 域名rator + "api" + 域名rator;
/**
* VUE_JS_PATH
*/
public static final String VUE_JS_PATH = "vueJsPath";
/**
* CUSTOM_FILE_PATH_MAP
*/
public static final String CUSTOM_FILE_PATH_MAP = "customFilePathMap";
}
3、mybatis-plus-generator3.5.1版本支持生成默认支持生成service、serviceImpl、mapper、mapperXml、controller、entity以及自定的other。这些文件都可以自定义模板和输出路径,但是mybatis-plus-generator是将所有的自定义文件都生成到other定义的目录下面的,这显然不符合我们的需求,比如我们需要的DTO文件,vue文件、js文件都会生成到不同的目录里面去,我们需要自定义扩展FreemarkerTemplateEngine方法,实现自定义文件生成到不同的目录,因为我们使用的是Freemarker所以自定义FreemarkerTemplateEngine这个实现类。
package 域名域名域名ne;
import 域名域名域名eInfo;
import 域名域名域名markerTemplateEngine;
import 域名;
import 域名;
/**
* Freemarker 自定义输出自定义模板文件
*
* @author GitEgg
* @since 2021-10-12
*/
public class GitEggFreemarkerTemplateEngine extends FreemarkerTemplateEngine {
/**
* 自定义输出自定义模板文件
*
* @param customFile 自定义配置模板文件信息
* @param tableInfo 表信息
* @param objectMap 渲染数据
* @since 3.5.1
*/
@Override
protected void outputCustomFile( Map<string, string=""> customFile, TableInfo tableInfo, Map<string, object=""> objectMap) {
Map<string, string=""> customFilePath = (Map<string, string="">)域名("customFilePathMap");
域名ach((key, value) -> {
String otherPath = 域名(key);
String fileName = 域名at((otherPath + 域名rator + "%s"), key);
outputFile(new File(fileName), objectMap, value);
});
}
}
二、业务及实现方法
代码生成作为系统的一个功能模块,也需要考虑业务、数据库设计,这里主要有这几个模块:
- 数据源配置:因为是微服务,可能会有多个数据库,分库分表等,所以这里选择使用配置数据源的方式,在代码生成的时候,让开发人员可以自己选择在哪个数据源下的表进行代码生成。
- 代码生成基础配置(数据字典):代码生成时用到的组件类型、展示类型等基础配置,都配置的代码生成的数据字典中,这里不使用系统的数据字典。同时,在组件选择时,只可以选择业务的数据字典。
- 校验规则配置:可以配置字段校验的正则表单式,在字段配置时选择哪些字段进行校验。
- 代码生成规则配置:数据表配置、联合表配置、字段配置、表单配置、 校验配置、列表配置
1、根据以上业务需求,设计了t_sys_code_generator_datasource(数据源配置)、t_sys_code_generator_config(主数据表配置)、t_sys_code_generator_table_join(联表配置)、t_sys_code_generator_field(表字段配置)、t_sys_code_generator_validate(校验规则配置)、t_sys_code_generator_dict(数据字典配置)共六张表。
CREATE TABLE `t_sys_code_generator_datasource` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'主键\',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT \'租户id\',
`datasource_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'数据源名称\',
`url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'连接地址\',
`username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'用户名\',
`password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'密码\',
`driver` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'数据库驱动\',
`db_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'数据库类型\',
`comments` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'备注\',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT \'创建时间\',
`creator` bigint(20) NULL DEFAULT NULL COMMENT \'创建者\',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT \'更新时间\',
`operator` bigint(20) NULL DEFAULT NULL COMMENT \'更新者\',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT \'1:删除 0:不删除\',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = \'数据源配置表\' ROW_FORMAT = Dynamic;
CREATE TABLE `t_sys_code_generator_config` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'主键\',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT \'租户id\',
`datasource_id` bigint(20) NULL DEFAULT NULL COMMENT \'数据源\',
`module_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'模块名称\',
`module_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'模块代码\',
`service_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'服务名称\',
`table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表名\',
`table_alias` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表别名\',
`table_prefix` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表前缀\',
`parent_package` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'父级包名\',
`controller_path` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'controller路径\',
`form_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表单类型 modal弹出框 drawer抽屉 tab新窗口\',
`table_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表类型 single单表 multi多表\',
`table_show_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'展示类型 table数据表格 tree_table 树表格 3 left_tree_table左树右表 tree数据树 table_table左表右表 left_table_tree左表右树\',
`form_item_col` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表单字段排列 1一列一行 2 两列一行\',
`left_tree_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'左树类型 organization机构树 resource资源权限树 \',
`front_code_path` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'前端代码路径\',
`service_code_path` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'后端代码路径\',
`import_flag` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'是否支持导入 1支持 0不支持\',
`export_flag` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'是否支持导出 1支持 0不支持\',
`query_reuse` tinyint(1) NOT NULL DEFAULT 1 COMMENT \'查询复用:分页查询和单条记录查询公用同一个sql语句\',
`status_handling` tinyint(1) NOT NULL DEFAULT 1 COMMENT \'状态处理\',
`code_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'0\' COMMENT \'代码生成类型 全部 仅后端代码 仅前端代码\',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT \'创建时间\',
`creator` bigint(20) NULL DEFAULT NULL COMMENT \'创建者\',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT \'更新时间\',
`operator` bigint(20) NULL DEFAULT NULL COMMENT \'更新者\',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT \'1:删除 0:不删除\',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = \'代码生成配置表\' ROW_FORMAT = Dynamic;
CREATE TABLE `t_sys_code_generator_table_join` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'主键\',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT \'租户id\',
`generation_id` bigint(20) NOT NULL COMMENT \'代码生成主键\',
`datasource_id` bigint(20) NULL DEFAULT NULL COMMENT \'数据源和主表一致\',
`join_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表名\',
`join_table_alias` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表别名\',
`join_table_prefix` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表前缀\',
`join_table_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'left左连接 right右连接 inner等值连接 union联合查询\',
`join_table_select` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'自定义查询字段\',
`join_table_on` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'自定义on条件\',
`table_sort` int(11) NULL DEFAULT NULL COMMENT \'显示排序\',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT \'创建时间\',
`creator` bigint(20) NULL DEFAULT NULL COMMENT \'创建者\',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT \'更新时间\',
`operator` bigint(20) NULL DEFAULT NULL COMMENT \'更新者\',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT \'1:删除 0:不删除\',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = \'多表查询时的联合表配置\' ROW_FORMAT = Dynamic;
CREATE TABLE `t_sys_code_generator_field` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'主键\',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT \'租户id\',
`generation_id` bigint(20) NOT NULL COMMENT \'代码生成主键\',
`join_id` bigint(20) NOT NULL COMMENT \'关联表主键\',
`join_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'表名\',
`field_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'字段名称\',
`field_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'字段类型\',
`comment` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'字段描述\',
`entity_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'实体类型\',
`entity_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'实体名称\',
`form_add` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'表单新增\',
`form_edit` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'表单编辑\',
`query_term` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'查询条件\',
`list_show` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'列表展示\',
`import_flag` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'是否支持导入 1支持 0不支持\',
`export_flag` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'是否支持导出 1支持 0不支持\',
`required` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'是否必填\',
`field_unique` tinyint(1) NOT NULL DEFAULT 0 COMMENT \'是否唯一\',
`query_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'查询类型\',
`control_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'组件类型\',
`dict_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'字典编码\',
`min` bigint(20) NULL DEFAULT NULL COMMENT \'最小值\',
`max` bigint(20) NULL DEFAULT NULL COMMENT \'最大值\',
`min_length` int(11) NOT NULL DEFAULT 0 COMMENT \'最小长度\',
`max_length` int(11) NULL DEFAULT NULL COMMENT \'字段最大长度\',
`default_value` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'默认值\',
`validate_id` bigint(20) NULL DEFAULT NULL COMMENT \'校验规则主键\',
`validate_regular` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'自定义正则表达式校验规则\',
`field_sort` int(11) NOT NULL DEFAULT 1 COMMENT \'显示排序\',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT \'创建时间\',
`creator` bigint(20) NULL DEFAULT NULL COMMENT \'创建者\',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT \'更新时间\',
`operator` bigint(20) NULL DEFAULT NULL COMMENT \'更新者\',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT \'1:删除 0:不删除\',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `unique_field`(`generation_id`, `join_id`, `join_table_name`, `field_name`) USING BTREE COMMENT \'联合约束\'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = \'字段属性配置表\' ROW_FORMAT = Dynamic;
CREATE TABLE `t_sys_code_generator_validate` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'主键\',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT \'租户id\',
`validate_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'校验名称\',
`validate_regular` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT \'正则表达式校验规则\',
`status` tinyint(2) NOT NULL DEFAULT 1 COMMENT \'\\'0\\'禁用,\\'1\\' 启用\',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT \'创建时间\',
`creator` bigint(20) NULL DEFAULT NULL COMMENT \'创建者\',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT \'更新时间\',
`operator` bigint(20) NULL DEFAULT NULL COMMENT \'更新者\',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT \'1:删除 0:不删除\',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = \'字段校验规则配置表\' ROW_FORMAT = Dynamic;
CREATE TABLE `t_sys_code_generator_dict` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'主键\',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT \'租户id\',
`parent_id` bigint(20) NULL DEFAULT NULL COMMENT \'字典上级\',
`ancestors` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT \'所有上级字典id的集合,便于查找\',
`dict_name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT \'字典名称\',
`dict_code` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT \'字典值\',
`dict_order` int(11) NULL DEFAULT NULL COMMENT \'排序\',
`dict_status` tinyint(2) NULL DEFAULT 1 COMMENT \'1有效,0禁用\',
`comments` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT \'备注\',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT \'创建时间\',
`creator` bigint(20) NULL DEFAULT NULL COMMENT \'创建人\',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT \'更新时间\',
`operator` bigint(20) NULL DEFAULT NULL COMMENT \'操作人\',
`del_flag` tinyint(2) NOT NULL DEFAULT 0 COMMENT \'1:删除 0:不删除\',
PRIMARY KEY (`id`) USING BTREE,
INDEX `INDEX_DICT_NAME`(`dict_name`) USING BTREE,
INDEX `INDEX_DICT_CODE`(`dict_code`) USING BTREE,
INDEX `INDEX_PARENT_ID`(`parent_id`) USING BTREE,
INDEX `INDEX_TENANT_ID`(`tenant_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = \'数据字典表\' ROW_FORMAT = Dynamic;
表结构建立好之后,先用mybatis-plus-generator默认功能生成基本的CRUD代码,这些CRUD代码就不列出来了,主要说明如何利用mybatis-plus-generator读取数据库表和字段,并结合业务在界面上展示,从而进行代码生成规则的配置。
2、在GitEgg-Cloud项目下,gitegg-plugin子项目下新建gitegg-code-generator工程,新建IEngineService接口和接口实现类EngineServiceImpl用于实现:查询某个数据源的所有表、查询某个表的字段信息、查询某个代码生成配置里面所有的字段配置、执行代码生成功能。
package 域名.域名ice;
import 域名域名域名eField;
import 域名域名域名eInfo;
import 域名.域名.QueryConfigDTO;
import 域名.域名.TableDTO;
import 域名;
/**
* 代码生成器接口
*
* @author GitEgg
*/
public interface IEngineService {
/**
* 查询某个数据源的所有表
*
* @param queryConfigDTO
* @return
*/
List<tabledto> queryTableList(QueryConfigDTO queryConfigDTO);
/**
* 查询某个数据源表的字段信息
*
* @param datasourceId
* @param tableNames
* @return
*/
List<tableinfo> queryTableFields(String datasourceId, List<string> tableNames);
/**
* 查询某个代码生成配置里面所有的字段
* @param queryConfigDTO
* @return
*/
List<tableinfo> queryConfigFields(QueryConfigDTO queryConfigDTO);
/**
* 执行代码生成
* @param queryConfigDTO
* @return
*/
boolean processGenerateCode(QueryConfigDTO queryConfigDTO);
}
package 域名.域名域名;
import 域名.域名til;
import 域名域名dFill;
import 域名域名pe;
import 域名域名域名yWrapper;
import 域名域名AutoGenerator;
import 域名域名域名SourceConfig;
import 域名域名域名utFile;
import 域名域名域名tegyConfig;
import 域名域名域名igBuilder;
import 域名域名域名eInfo;
import 域名域名域名ngStrategy;
import 域名域名.Column;
import 域名.域名.QueryConfigDTO;
import 域名.域名域名ig;
import 域名.域名域名figService;
import 域名.域名域名source;
import 域名.域名域名asourceService;
import 域名.域名ggDatabaseQuery;
import 域名.域名域名GeneratorConstant;
import 域名.域名.TableDTO;
import 域名.域名域名omFileEnum;
import 域名.域名域名ineService;
import 域名.域名.FieldDTO;
import 域名.域名.QueryFieldDTO;
import 域名.域名域名ldService;
import 域名.域名域名eJoin;
import 域名.域名域名leJoinService;
import 域名域名域名EntityEnum;
import 域名域名域名ggCodeGeneratorConstant;
import 域名域名域名ggFreemarkerTemplateEngine;
import 域名域名域名Entity;
import 域名iredArgsConstructor;
import 域名域名j;
import 域名域名域名wired;
import 域名域名;
import 域名域名ice;
import 域名.CollectionUtils;
import 域名;
import 域名yList;
import 域名Map;
import 域名;
import 域名;
import 域名域名ectors;
/**
* 代码生成器接口类
*
* @author GitEgg
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class EngineServiceImpl implements IEngineService {
private final IConfigService configService;
private final IDatasourceService datasourceService;
private final ITableJoinService tableJoinService;
/**
* 解决循环依赖问题
*/
private IFieldService fieldService;
@Autowired
public void setFieldService(@Lazy IFieldService fieldService) {
域名dService = fieldService;
}
@Override
public List<tabledto> queryTableList(QueryConfigDTO queryConfigDTO) {
Datasource datasource = 域名yId(域名atasourceId());
DataSourceConfig dataSourceConfig = new 域名der(域名rl(), 域名sername(), 域名assword()).build();
ConfigBuilder configBuilder = new ConfigBuilder(null, dataSourceConfig, null, null, null, null);
List<tabledto> tableInfos = (new GitEggDatabaseQuery(configBuilder)).queryDatasourceTables();
return tableInfos;
}
@Override
public List<tableinfo> queryTableFields(String datasourceId, List<string> tableNames) {
Datasource datasource = 域名yId(datasourceId);
DataSourceConfig dataSourceConfig = new 域名der(域名rl(), 域名sername(), 域名assword()).build();
//设置有哪些表
StrategyConfig strategyConfig = new 域名der()
.addInclude(域名ray(new String[]{}))
.entityBuilder()
.enableChainModel()
.enableLombok()
.enableRemoveIsPrefix()
.enableTableFieldAnnotation()
.enableActiveRecord()
.logicDeleteColumnName(域名d)
.logicDeletePropertyName(域名ty)
.naming(域名rline_to_camel)
.columnNaming(域名rline_to_camel)
.addTableFills(new Column(域名d, 域名RT))
.addTableFills(new Column(域名d, 域名RT_UPDATE))
.idType(域名)
.build();
ConfigBuilder configBuilder = new ConfigBuilder(null, dataSourceConfig, strategyConfig, null, null, null);
List<tableinfo> tableInfoList = 域名ableInfoList();
return tableInfoList;
}
@Override
public List<tableinfo> queryConfigFields(QueryConfigDTO queryConfigDTO) {
List<string> tableNames = new ArrayList<>();
String tableName = 域名ableName();
域名(tableName);
Long id = 域名d();
// 查询是否有联表
if (域名ls(域名ableType()))
{
QueryWrapper<tablejoin> queryWrapper = new QueryWrapper<>();
域名(域名RATION_ID, id);
List<tablejoin> tableJoinList = 域名(queryWrapper);
if(!域名pty(tableJoinList))
{
域名am().forEach(tableJoin->{
域名(域名oinTableName());
});
}
}
Datasource datasource = 域名yId(域名atasourceId());
DataSourceConfig dataSourceConfig = new 域名der(域名rl(), 域名sername(), 域名assword()).build();
//设置有哪些表
StrategyConfig strategyConfig = new 域名der().addInclude(域名ray(new String[]{})).build();
ConfigBuilder configBuilder = new ConfigBuilder(null, dataSourceConfig, strategyConfig, null, null, null);
List<tableinfo> tableInfoList = 域名ableInfoList();
return tableInfoList;
}
@Override
public boolean processGenerateCode(QueryConfigDTO queryConfigDTO){
Config config = 域名yId(域名d());
QueryFieldDTO queryFieldDTO = new QueryFieldDTO();
域名enerationId(域名d());
List<fielddto> fieldDTOS = 域名yFieldList(queryFieldDTO);
//提取表单的字段
List<fielddto> formFieldDTOS = 域名am().filter(f->域名ormAdd() || 域名ormEdit()).collect(域名st());
Map<string, object=""> customMap = new HashMap<>();
域名(域名IG, config);
域名(域名DS, fieldDTOS);
域名(域名_FIELDS, formFieldDTOS);
//baseEntity里面有的,DTO中需要排除的字段
List<string> baseEntityFieldList = 域名aseEntityFieldList();
域名(域名_ENTITY_FIELD_LIST, baseEntityFieldList);
//查询数据源配置
Datasource datasource = 域名yId(域名atasourceId());
String serviceName = 域名erviceName();
//前端代码路径
String frontCodePath = 域名rontCodePath();
//后端代码路径
String serviceCodePath = 域名erviceCodePath();
//自定义路径
String parent = 域名arentPackage();
String moduleName = 域名oduleCode();
String codeDirPath = (parent + 域名 + moduleName).replace(域名, 域名rator) + 域名rator;
域名te(域名rl(), 域名sername(), 域名assword())
.globalConfig(builder -> {
//全局配置
String author = 域名OR;
域名or(author) // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.disableOpenDir()
.outputDir(serviceCodePath + 域名_PATH); // 指定输出目录
})
.packageConfig(builder -> {
//包配置
Map<outputfile, string=""> pathInfoMap = new HashMap<>();
域名(域名erXml, serviceCodePath + 域名URCES_PATH + codeDirPath + 域名ER);
域名nt(parent) // 设置父包名
.moduleName(moduleName) // 设置父包模块名
.pathInfo(pathInfoMap); // 自定义生成路径
})
.injectionConfig(builder -> {
String dtoName = 域名rFirst(域名oduleCode());
//dto
String dtoFile = dtoName + 域名JAVA;
String createDtoFile = 域名TE + dtoFile;
String updateDtoFile = 域名TE + dtoFile;
String queryDtoFile = 域名Y + dtoFile;
//Export and Import
String exportFile = dtoName + 域名RT_JAVA;
String importFile = dtoName + 域名RT_JAVA;
// SQL
String sqlFile = dtoName + 域名URCE_SQL;
// 设置自定义输出文件
Map<string, string=""> customFileMap = new HashMap<>();
域名(dtoFile, 域名);
域名(createDtoFile, 域名);
域名(updateDtoFile, 域名);
域名(queryDtoFile, 域名);
// Export and Import
域名(exportFile, 域名);
域名(importFile, 域名);
// SQL
域名(sqlFile, 域名);
//因为目前版本框架只支持自定义输出到other目录,所以这里利用重写AbstractTemplateEngine的outputCustomFile方法支持所有自定义文件输出目录
Map<string, string=""> customFilePath = new HashMap<>();
int start = 域名xOf(域名ED);
int end = 域名th();
String servicePath = 域名tring(start, end).replace(域名ED, 域名rator);
//判断是否生成后端代码
if (域名odeType().equals(域名_ALL) || 域名odeType().equals(域名_SERVICE))
{
//dto
String dtoPath = serviceCodePath + 域名_PATH + codeDirPath + 域名;
域名(dtoFile, dtoPath);
域名(createDtoFile, dtoPath);
域名(updateDtoFile, dtoPath);
域名(queryDtoFile, dtoPath);
// Export and Import
String entityPath = serviceCodePath + 域名_PATH + codeDirPath + 域名TY;
域名(exportFile, entityPath);
域名(importFile, entityPath);
// SQL
String sqlPath = serviceCodePath + 域名URCES_PATH + codeDirPath + 域名ER;
域名(sqlFile, sqlPath);
}
//判断是否生成后端代码
if (域名odeType().equals(域名_ALL) || 域名odeType().equals(域名_FRONT))
{
// vue and js
String vueFile = 域名oduleCode() + 域名E_VUE;
String jsFile = 域名oduleCode() + 域名;
String vuePath = frontCodePath + 域名PATH + servicePath + 域名rator + 域名oduleCode();
String jsPath = frontCodePath + 域名ATH + servicePath + 域名rator + 域名oduleCode();
域名(vueFile, vuePath);
域名(jsFile, jsPath);
// VUE AND JS
// TODO 要支持树形表、左树右表、左表右表、左表右树、左树右树形表、左树右树
域名(vueFile, 域名);
域名(jsFile, 域名);
域名(域名JS_PATH, 域名ace(域名rator, 域名H) + 域名H + 域名oduleCode() + 域名H + 域名oduleCode());
}
域名(域名OM_FILE_PATH_MAP, customFilePath);
域名omMap(customMap)
.customFile(customFileMap);
})
.strategyConfig(builder -> {
builder
.addInclude(域名ableName())
.addTablePrefix(域名ablePrefix())
.entityBuilder()
.enableLombok()
.enableTableFieldAnnotation() // 实体字段注解
.superClass(域名s)
.addSuperEntityColumns(域名d, 域名d,
域名d, 域名d, 域名d, 域名d)
.naming(域名rline_to_camel)
.addTableFills(new Column(域名d, 域名RT)) //基于数据库字段填充
.addTableFills(new Column(域名d, 域名RT_UPDATE)) //基于模型属性填充
.controllerBuilder()
.enableRestStyle()
.enableHyphenStyle()
.mapperBuilder()
// .enableMapperAnnotation()
.enableBaseResultMap()
.enableBaseColumnList()
;
})
.templateConfig(builder -> {
if (域名odeType().equals(域名_FRONT)) {
域名ble();
}
})
// 使用Freemarker引擎模板,默认的是Velocity引擎模板
.templateEngine(new GitEggFreemarkerTemplateEngine())
.execute();
return true;
}
}
3、修改代码生成的模板文件,因为默认的代码模板生成文件不能满足我们的需求,我们需要新增DTO、vue、js、数据导入导出实体定义类等模板,在模板接口新增导入导出等方法,在DTO添加字段校验等。因为模板代码太多,这里不详细列举,可以在在GitHub 或者 Gitee下载查看。
4、代码生成功能运行界面
数据源配置:
代码生成配置:
关联表配置:
表字段配置:
表单配置:
表单校验配置:
列表查询配置:
数据字典配置:
校验规则配置:
源码地址:
Gitee: https://域名/wmz1930/GitEgg
GitHub: https://域名/wmz1930/GitEgg