需求描述:
1,SpringBoot项目
2,需要自动生成 controller层、service层、mapper接口、mapper.xml、实体类、自定义扩展类等
3,连接的数据库是 gauss db
4,mybatis-generate 本身的模板及模板参数固定,无法扩展到更多自定义类,需要更改源码实现
5,自动生成单元测试类等操作
实现:
1,引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MySQL 连接驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<!--高斯DB 驱动-->
<dependency>
<groupId>com.huawei.gauss</groupId>
<artifactId>com.huawei.gauss.jdbc.ZenithDriver</artifactId>
<version>1.5.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.33</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
<!--Excel工具-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- swagger-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
2,resources下面配置文件 application.yml
spring:
datasource:
driver-class-name: com.huawei.gauss.jdbc.inner.GaussDriver
url: jdbc:zenith:xxxx
username: xxxx
password: xxxx
3,编写代码
入口执行类 MpGeneratorUtil
package com.taia.yms.generate;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.taia.yms.controller.AbstractControllerTest;
import com.taia.yms.entity.ExportPageReqBody;
import com.taia.yms.entity.TableBasicInfo;
import com.taia.yms.fileutils3.filefactory.AbstractDefaultSheetFactory;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.StringUtils;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@SpringBootTest
@WebAppConfiguration
@Slf4j
public class MpGeneratorUtil {
private DbType dbType = DbType.GAUSS;
private ITypeConvert typeConverter = new GaussDbTypeConvert();
private IDbQuery iDbQuery = new GaussDbQuery();
//连接数据的信息(在配置文件中)
@Value("${spring.datasource.driver-class-name}")
private String sysDriverName;
@Value("${spring.datasource.url}")
private String sysUrl;
@Value("${spring.datasource.username}")
private String sysUserName;
@Value("${spring.datasource.password}")
private String sysPassword;
//固定参数
private static final String OUTPUT_DIR_ROOT = "/generate/src/main/java";
private static final String LOGIC_DELETE_FIELD_NAME = "status";//逻辑删除
private static final String PARENT_PACKAGE = "com.taia.yms";
private static final String AUTHOR = "loren";
//entity 表实体对象后缀
private static final String MAIN_LAST_ENTITY_NAME = "Tab";
//一般请求 如 新增、修改等 的入参后缀
private static final String REQ_BODY_LAST_ENTITY_NAME = "ReqBody";
//列表查询 或 导出等 的入参后缀
private static final String PAGE_REQ_BODY_LAST_ENTITY_NAME = "PageReqBody";
private static final String FILE_LAST_ENTITY_NAME = "File";
private static final String Test_LAST_ENTITY_NAME = "ControllerTest";
//从父类继承的字段 / 主表过滤字段
private static final List<String> EXTEND_COLUMNS = Arrays.asList(
"LAST_UPDATED_BY","LAST_UPDATED_BY_NAME","LAST_UPDATED_TIME","CREATED_BY","CREATED_BY_NAME","CREATED_TIME","STATUS"
);
@Test
public void generator() {
String tableName = "T_COMM_CAPTURE_RATE_CONFIG";
String tableSequence = "SEQ_COMM_CAPTURE_RATE_CONFIG";
//以下三个集合必须是 _ 连接,即 同数据库的表字段格式,可以不区分大小写
// 注 需要使用实际查询的字段,便于模板中字段进行映射 --- 模板文件相同
List<String> selectList = Arrays.asList("fab", "LOT_ID", "Equipment_ID", "step_Id","Tolerance");
List<String> primaryKeyList = Arrays.asList("LOT_ID", "Equipment_ID", "step_Id");
String pathVersion = "v1",substrPrefix = "T_COMM_";
//注:每次生成都需要重新生成 AutoGeneratorNew,不能复用
AutoGeneratorNew autoGeneratorNew = getAutoGeneratorNew(tableName);
//调用自动生成代码逻辑 将数据库信息 代码作者 接口false
autoGeneratorNew.setLastEntityName(MAIN_LAST_ENTITY_NAME).setEntityPackage("entity.table")
//controller 设置
.setControllerApiTags("Captrue Rate配置")
.setPathVersion(pathVersion).setSubstrPrefix(substrPrefix)
//唯一性校验
.setPrimaryKeys(primaryKeyList).setTableSequence(tableSequence)
//列表查询筛选字段
.setSelectList(selectList)
;
generatorMain(autoGeneratorNew);
//生成多余的实体类
//reqBody
AutoGeneratorNew autoGeneratorNew1 = getAutoGeneratorNew(tableName);
autoGeneratorNew1.setLastEntityName(REQ_BODY_LAST_ENTITY_NAME).setEntityPackage("entity.reqBody")
.setSuperEntityClass(TableBasicInfo.class);
generatorOtherEntity(autoGeneratorNew1);
//pageReqBody
AutoGeneratorNew autoGeneratorNew2 = getAutoGeneratorNew(tableName);
autoGeneratorNew2.setLastEntityName(PAGE_REQ_BODY_LAST_ENTITY_NAME).setEntityPackage("entity.reqBody")
.setSuperEntityClass(ExportPageReqBody.class);
generatorOtherEntity(autoGeneratorNew2);
//导入导出对象 文件
AutoGeneratorNew autoGeneratorNew3 = getAutoGeneratorNew(tableName);
autoGeneratorNew3.setLastEntityName(FILE_LAST_ENTITY_NAME).setEntityPackage("fileutils3.service")
.setTemplateName("file").setFileConfigName("Captrue Rate")
.setFileFields(selectList)
.setSuperEntityClass(AbstractDefaultSheetFactory.class);
generatorOtherEntity(autoGeneratorNew3);
//单元测试
AutoGeneratorNew autoGeneratorNew4 = getAutoGeneratorNew(tableName)
.setPathVersion(pathVersion).setSubstrPrefix(substrPrefix);
autoGeneratorNew4.setLastEntityName(Test_LAST_ENTITY_NAME).setEntityPackage("controller")
.setSuperEntityClass(AbstractControllerTest.class).setTemplateName("test");
generatorOtherEntity(autoGeneratorNew4);
}
@Test
public void onlyGenerateTest() {
String tableName = "T_COMM_DEFECT_AREA_LIMIT";
String pathVersion = "v2",substrPrefix = "T_COMM_";
//单元测试
AutoGeneratorNew autoGeneratorNew4 = getAutoGeneratorNew(tableName)
.setPathVersion(pathVersion).setSubstrPrefix(substrPrefix);
autoGeneratorNew4.setLastEntityName(Test_LAST_ENTITY_NAME).setEntityPackage("controller")
.setSuperEntityClass(AbstractControllerTest.class).setTemplateName("test");
generatorOtherEntity(autoGeneratorNew4);
}
private AutoGeneratorNew getAutoGeneratorNew(String tableName) {
// 数据源配置
DataSourceConfig dsc = getDataSourceConfig();
FreemarkerTemplateEngineNew templateEngineNew = new FreemarkerTemplateEngineNew();
AutoGeneratorNew autoGeneratorNew = AutoGeneratorNew.builder()
.systemTable(tableName).build();
autoGeneratorNew.setDataSource(dsc);
autoGeneratorNew.setTemplateEngine(templateEngineNew);
return autoGeneratorNew;
}
private void generatorMain(AutoGeneratorNew autoGenerator) {
// 全局配置
GlobalConfig gc = getGlobalConfig(AUTHOR, autoGenerator.getLastEntityName());
// 自定义文件命名,注意 %s 会自动填充表实体属性!
gc.setServiceName("%sService"); //默认是I**Service
autoGenerator.setGlobalConfig(gc);
// 策略配置
StrategyConfig strategy = getStrategyConfig(autoGenerator.getSystemTable());
strategy.setRestControllerStyle(true);
autoGenerator.setStrategy(strategy);
// 包配置
setPackageInfo(autoGenerator);
autoGenerator.setTemplate(new TemplateConfig());
autoGenerator.execute();
}
private void generatorOtherEntity(AutoGeneratorNew autoGenerator) {
// 全局配置
GlobalConfig gc = getGlobalConfig(AUTHOR, autoGenerator.getLastEntityName());
autoGenerator.setGlobalConfig(gc);
// 数据源配置
((GaussDbQuery)iDbQuery).setFilterColumns(EXTEND_COLUMNS);
// 策略配置
StrategyConfig strategy = getStrategyConfig(autoGenerator.getSystemTable());
//设置实体类 父类基类 -> 无法排除掉父类中相同属性字段
if(autoGenerator.getSuperEntityClass() != null){
strategy.setSuperEntityClass(autoGenerator.getSuperEntityClass());
}
autoGenerator.setStrategy(strategy);
setPackageInfo(autoGenerator);
//自定义生成多余的实体类
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setController(null); //不生成controller或者可以设置模板
templateConfig.setService(null); //不生成service或者可以设置模板
templateConfig.setServiceImpl(null); //不生成serviceImpl或者可以设置模板
templateConfig.setMapper(null); //不生成mapper或者可以设置模板
templateConfig.setXml(null); //不生成xml或者可以设置模板
if(StringUtils.hasText(autoGenerator.getTemplateName())){
//自定义 导入导出 模板文件
templateConfig.setEntity("templates/"+autoGenerator.getTemplateName()+".java");
}
autoGenerator.setTemplate(templateConfig);
autoGenerator.execute();
}
private static void setPackageInfo(AutoGeneratorNew autoGenerator) {
// 包配置
PackageConfig pc = new PackageConfig();
//这里需要修改成为你的包路径 生成后的三层架构就在test包下即可查看
pc.setParent(PARENT_PACKAGE).setEntity(autoGenerator.getEntityPackage());
autoGenerator.setPackageInfo(pc);
}
private static StrategyConfig getStrategyConfig(String systemTable) {
StrategyConfig strategy = new StrategyConfig();
strategy.setCapitalMode(true)// 全局大写命名 ORACLE 注意
.setNaming(NamingStrategy.underline_to_camel) // 数据库字段下划线转驼峰命令策略
.setInclude(systemTable) // 需要生成的表 单次传一张表
.setEntityLombokModel(true)//启动 lombok 注解
//设置逻辑删除字段
.setLogicDeleteFieldName(LOGIC_DELETE_FIELD_NAME);
return strategy;
}
private static GlobalConfig getGlobalConfig(String author, String lastEntityName) {
File file = new File("");
GlobalConfig gc = new GlobalConfig();
//测试下运行获取的路径是模块下的位置,所以需要加../
gc.setOutputDir(file.getAbsolutePath() + OUTPUT_DIR_ROOT)
.setFileOverride(true)
.setActiveRecord(false)// 不需要ActiveRecord特性的请改为false
.setAuthor(author)
.setEntityName("%s"+lastEntityName)
;
return gc;
}
private static InjectionConfig getInjectionConfig() {
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
@Override
public void initTableMap(TableInfo tableInfo) {
Map<String, Object> map = this.getMap();
log.info("获取所有表字段属性信息:{}", JSON.toJSONString(tableInfo));
}
};
return cfg;
}
private DataSourceConfig getDataSourceConfig() {
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(dbType)
.setDbQuery(iDbQuery)
.setTypeConvert(typeConverter)
.setDriverName(sysDriverName)
.setUrl(sysUrl)
.setUsername(sysUserName)
.setPassword(sysPassword);
return dsc;
}
}
自定义 AutoGeneratorNew
package com.taia.yms.generate;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@Slf4j
public class AutoGeneratorNew extends AutoGenerator {
private String systemTable;
private String lastEntityName;
private Class superEntityClass;
//@Api 的tags值
private String controllerApiTags;
//controller层请求地址 前缀 如 v1
private String pathVersion;
private String substrPrefix;
private TableInfo tableInfo;
//实体类的包路径
private String entityPackage;
//其他对象设置
private String templateName;
//表自增索引
private String tableSequence;
private String fileConfigName;
private List<String> fileFields;
private String fileFieldsStr;
private List<String> primaryKeys;
private List<String> selectList;
@Override
public void execute() {
log.debug("==========================准备生成文件...==========================");
if (null == this.config) {
this.config = new ConfigBuilder(this.getPackageInfo(), this.getDataSource(), this.getStrategy(), this.getTemplate(), this.getGlobalConfig());
if (null != this.injectionConfig) {
this.injectionConfig.setConfig(this.config);
}
}
if (null == this.getTemplateEngine()) {
this.setTemplateEngine(new VelocityTemplateEngine());
}
if(this.getTemplateEngine() instanceof FreemarkerTemplateEngineNew){
((FreemarkerTemplateEngineNew)this.getTemplateEngine().init(this.pretreatmentConfigBuilder(this.config)).mkdirs())
.batchOutput(this);
}else{
this.getTemplateEngine().init(this.pretreatmentConfigBuilder(this.config)).mkdirs()
.batchOutput().open();
}
log.debug("==========================文件生成完成!!!==========================");
}
}
自定义模板引擎类 FreemarkerTemplateEngineNew
package com.taia.yms.generate;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.taia.yms.utils.OperateUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
public class FreemarkerTemplateEngineNew extends AbstractTemplateEngine {
private Configuration configuration;
public FreemarkerTemplateEngineNew() {
}
public AbstractTemplateEngine batchOutput(AutoGeneratorNew autoGeneratorNew) {
try {
List<TableInfo> tableInfoList = this.getConfigBuilder().getTableInfoList();
Iterator var2 = tableInfoList.iterator();
while(var2.hasNext()) {
TableInfo tableInfo = (TableInfo)var2.next();
autoGeneratorNew.setTableInfo(tableInfo);
Map<String, Object> objectMap = this.getObjectMap(autoGeneratorNew);
Map<String, String> pathInfo = this.getConfigBuilder().getPathInfo();
TemplateConfig template = this.getConfigBuilder().getTemplate();
InjectionConfig injectionConfig = this.getConfigBuilder().getInjectionConfig();
if (null != injectionConfig) {
injectionConfig.initTableMap(tableInfo);
objectMap.put("cfg", injectionConfig.getMap());
List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
if (CollectionUtils.isNotEmpty(focList)) {
Iterator var9 = focList.iterator();
while(var9.hasNext()) {
FileOutConfig foc = (FileOutConfig)var9.next();
if (this.isCreate(FileType.OTHER, foc.outputFile(tableInfo))) {
this.writer(objectMap, foc.getTemplatePath(), foc.outputFile(tableInfo));
}
}
}
}
String entityName = tableInfo.getEntityName();
String controllerFile;
if (null != entityName && null != pathInfo.get("entity_path")) {
controllerFile = String.format((String)pathInfo.get("entity_path") + File.separator + "%s" + this.suffixJavaOrKt(), entityName);
if (this.isCreate(FileType.ENTITY, controllerFile)) {
this.writer(objectMap, this.templateFilePath(template.getEntity(this.getConfigBuilder().getGlobalConfig().isKotlin())), controllerFile);
}
}
if (null != tableInfo.getMapperName() && null != pathInfo.get("mapper_path")) {
controllerFile = String.format((String)pathInfo.get("mapper_path") + File.separator + tableInfo.getMapperName() + this.suffixJavaOrKt(), entityName);
if (this.isCreate(FileType.MAPPER, controllerFile)) {
this.writer(objectMap, this.templateFilePath(template.getMapper()), controllerFile);
}
}
if (null != tableInfo.getXmlName() && null != pathInfo.get("xml_path")) {
controllerFile = String.format((String)pathInfo.get("xml_path") + File.separator + tableInfo.getXmlName() + ".xml", entityName);
if (this.isCreate(FileType.XML, controllerFile)) {
this.writer(objectMap, this.templateFilePath(template.getXml()), controllerFile);
}
}
if (null != tableInfo.getServiceName() && null != pathInfo.get("service_path")) {
controllerFile = String.format((String)pathInfo.get("service_path") + File.separator + tableInfo.getServiceName() + this.suffixJavaOrKt(), entityName);
if (this.isCreate(FileType.SERVICE, controllerFile)) {
this.writer(objectMap, this.templateFilePath(template.getService()), controllerFile);
}
}
if (null != tableInfo.getServiceImplName() && null != pathInfo.get("service_impl_path")) {
controllerFile = String.format((String)pathInfo.get("service_impl_path") + File.separator + tableInfo.getServiceImplName() + this.suffixJavaOrKt(), entityName);
if (this.isCreate(FileType.SERVICE_IMPL, controllerFile)) {
this.writer(objectMap, this.templateFilePath(template.getServiceImpl()), controllerFile);
}
}
if (null != tableInfo.getControllerName() && null != pathInfo.get("controller_path")) {
controllerFile = String.format((String)pathInfo.get("controller_path") + File.separator + tableInfo.getControllerName() + this.suffixJavaOrKt(), entityName);
if (this.isCreate(FileType.CONTROLLER, controllerFile)) {
this.writer(objectMap, this.templateFilePath(template.getController()), controllerFile);
}
}
}
} catch (Exception var11) {
logger.error("无法创建文件,请检查配置信息!", var11);
}
return this;
}
public Map<String, Object> getObjectMap(AutoGeneratorNew autoGeneratorNew) {
TableInfo tableInfo = autoGeneratorNew.getTableInfo();
Map<String, Object> objectMap = new HashMap(30);
ConfigBuilder config = this.getConfigBuilder();
if (config.getStrategyConfig().isControllerMappingHyphenStyle()) {
objectMap.put("controllerMappingHyphenStyle", config.getStrategyConfig().isControllerMappingHyphenStyle());
objectMap.put("controllerMappingHyphen", StringUtils.camelToHyphen(tableInfo.getEntityPath()));
}
objectMap.put("restControllerStyle", config.getStrategyConfig().isRestControllerStyle());
objectMap.put("config", config);
objectMap.put("package", config.getPackageInfo());
GlobalConfig globalConfig = config.getGlobalConfig();
objectMap.put("author", globalConfig.getAuthor());
objectMap.put("idType", globalConfig.getIdType() == null ? null : globalConfig.getIdType().toString());
objectMap.put("logicDeleteFieldName", config.getStrategyConfig().getLogicDeleteFieldName());
objectMap.put("versionFieldName", config.getStrategyConfig().getVersionFieldName());
objectMap.put("activeRecord", globalConfig.isActiveRecord());
objectMap.put("kotlin", globalConfig.isKotlin());
objectMap.put("swagger2", globalConfig.isSwagger2());
objectMap.put("date", (new SimpleDateFormat("yyyy-MM-dd")).format(new Date()));
objectMap.put("table", tableInfo);
objectMap.put("enableCache", globalConfig.isEnableCache());
objectMap.put("baseResultMap", globalConfig.isBaseResultMap());
objectMap.put("baseColumnList", globalConfig.isBaseColumnList());
objectMap.put("entity", tableInfo.getEntityName());
objectMap.put("entitySerialVersionUID", config.getStrategyConfig().isEntitySerialVersionUID());
objectMap.put("entityColumnConstant", config.getStrategyConfig().isEntityColumnConstant());
objectMap.put("entityBuilderModel", config.getStrategyConfig().isEntityBuilderModel());
objectMap.put("chainModel", config.getStrategyConfig().isChainModel());
objectMap.put("entityLombokModel", config.getStrategyConfig().isEntityLombokModel());
objectMap.put("entityBooleanColumnRemoveIsPrefix", config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix());
objectMap.put("superEntityClass", this.getSuperClassName(config.getSuperEntityClass()));
objectMap.put("superMapperClassPackage", config.getSuperMapperClass());
objectMap.put("superMapperClass", this.getSuperClassName(config.getSuperMapperClass()));
objectMap.put("superServiceClassPackage", config.getSuperServiceClass());
objectMap.put("superServiceClass", this.getSuperClassName(config.getSuperServiceClass()));
objectMap.put("superServiceImplClassPackage", config.getSuperServiceImplClass());
objectMap.put("superServiceImplClass", this.getSuperClassName(config.getSuperServiceImplClass()));
objectMap.put("superControllerClassPackage", this.verifyClassPacket(config.getSuperControllerClass()));
objectMap.put("superControllerClass", this.getSuperClassName(config.getSuperControllerClass()));
//设置 controller api Tags 或者 日志 pageName
objectMap.put("apiTags",autoGeneratorNew.getControllerApiTags());
objectMap.put("pathVersion",autoGeneratorNew.getPathVersion());
//表名 驼峰命名
String name = tableInfo.getName();
String processName = OperateUtils.processName(name, NamingStrategy.underline_to_camel);
String originEntityName = NamingStrategy.capitalFirst(processName);
objectMap.put("reqBodyEntity",originEntityName+"ReqBody");
objectMap.put("pageReqBodyEntity",originEntityName+"PageReqBody");
objectMap.put("fileEntity",originEntityName+"File");
objectMap.put("originEntityName",originEntityName);
String substrPrefix = autoGeneratorNew.getSubstrPrefix();
if(org.springframework.util.StringUtils.hasText(substrPrefix) && name.length() > substrPrefix.length()){
processName = OperateUtils.processName(name.substring(substrPrefix.length()), NamingStrategy.underline_to_camel);
}
objectMap.put("processName",processName);
//设置文件相关信息
objectMap.put("fileConfigName",autoGeneratorNew.getFileConfigName());
if(CollectionUtils.isNotEmpty(autoGeneratorNew.getFileFields())){
//大写
objectMap.put("fileFields",autoGeneratorNew.getFileFields().stream()
.map(v-> v.toUpperCase()).collect(Collectors.toList()));
objectMap.put("fileFieldsStr",autoGeneratorNew.getFileFields().stream().collect(Collectors.joining(",")));
}
if(CollectionUtils.isNotEmpty(autoGeneratorNew.getPrimaryKeys())){
List<String> primaryKeys = autoGeneratorNew.getPrimaryKeys();
String primaryKeyStr = primaryKeys.stream().map(v ->
//转换为首字母大写,驼峰
NamingStrategy.capitalFirst(OperateUtils.processName(v, NamingStrategy.underline_to_camel))
+ "=[%s]").collect(Collectors.joining(","));
objectMap.put("primaryKeys",primaryKeys.stream().map(v-> v.toUpperCase()).collect(Collectors.toList()));
objectMap.put("primaryKeyStr",primaryKeyStr);
String getPrimaryKeyStr = primaryKeys.stream().map(v -> "reqBody.get" +
//转换为首字母大写,驼峰
NamingStrategy.capitalFirst(OperateUtils.processName(v, NamingStrategy.underline_to_camel))
+"()").collect(Collectors.joining(","));
objectMap.put("getPrimaryKeyStr",getPrimaryKeyStr);
}
if(CollectionUtils.isNotEmpty(autoGeneratorNew.getSelectList())){
List<String> selectList = autoGeneratorNew.getSelectList();
List<String> list = selectList.stream().map(v -> v.toUpperCase()).collect(Collectors.toList());
objectMap.put("selectList",list);
}
//自增序列
objectMap.put("tableSequence",autoGeneratorNew.getTableSequence());
return (Objects.isNull(config.getInjectionConfig()) ? objectMap : config.getInjectionConfig().prepareObjectMap(objectMap));
}
private String getSuperClassName(String classPath) {
return StringUtils.isBlank(classPath) ? null : classPath.substring(classPath.lastIndexOf(".") + 1);
}
private String verifyClassPacket(String classPacket) {
return StringUtils.isBlank(classPacket) ? null : classPacket;
}
public FreemarkerTemplateEngineNew init(ConfigBuilder configBuilder) {
super.init(configBuilder);
this.configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
this.configuration.setDefaultEncoding(ConstVal.UTF8);
this.configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, "/");
return this;
}
public void writer(Map<String, Object> objectMap, String templatePath, String outputFile) throws Exception {
Template template = this.configuration.getTemplate(templatePath);
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
Throwable var6 = null;
try {
template.process(objectMap, new OutputStreamWriter(fileOutputStream, ConstVal.UTF8));
} catch (Throwable var15) {
var6 = var15;
throw var15;
} finally {
if (fileOutputStream != null) {
if (var6 != null) {
try {
fileOutputStream.close();
} catch (Throwable var14) {
var6.addSuppressed(var14);
}
} else {
fileOutputStream.close();
}
}
}
logger.debug("模板:" + templatePath + "; 文件:" + outputFile);
}
public String templateFilePath(String filePath) {
return filePath + ".ftl";
}
}
自定义 gaussdb 类型转换器 GaussDbTypeConvert
package com.taia.yms.generate;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.ITypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.GaussTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
public class GaussDbTypeConvert implements ITypeConvert {
public GaussDbTypeConvert() {
}
public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
String t = fieldType.toLowerCase();
return (new GaussDbTypeConvert.BasicDataTypeHandler()).getDbColumnType(t);
}
class MultimediaDataTypeHandler implements GaussDbTypeConvert.Handler {
MultimediaDataTypeHandler() {
}
public DbColumnType getDbColumnType(String fieldType) {
if (!fieldType.contains("text") && !fieldType.contains("longvarchar")) {
if (fieldType.contains("clob")) {
return DbColumnType.CLOB;
} else if (fieldType.contains("blob")) {
return DbColumnType.BLOB;
} else {
return fieldType.contains("image") ? DbColumnType.BYTE_ARRAY : DbColumnType.STRING;
}
} else {
return DbColumnType.STRING;
}
}
}
class DateTimeDataTypeHandler implements GaussDbTypeConvert.Handler {
DateTimeDataTypeHandler() {
}
public DbColumnType getDbColumnType(String fieldType) {
return fieldType.contains("timestamp") ? DbColumnType.TIMESTAMP : (
!fieldType.contains("date") && !fieldType.contains("time") ?
(GaussDbTypeConvert.this.new MultimediaDataTypeHandler()).getDbColumnType(fieldType) : DbColumnType.DATE
)
;
}
}
class BasicDataTypeHandler implements GaussDbTypeConvert.Handler {
BasicDataTypeHandler() {
}
public DbColumnType getDbColumnType(String fieldType) {
if (fieldType.contains("char")) {
return DbColumnType.STRING;
} else if (!fieldType.contains("numeric") && !fieldType.contains("decimal") && !fieldType.contains("dec") && !fieldType.contains("money")) {
if (!fieldType.contains("bit") && !fieldType.contains("bool") && !fieldType.contains("boolean")) {
if (!fieldType.contains("integer") && !fieldType.contains("int")) {
if (!fieldType.contains("tinyint") && !fieldType.contains("byte") && !fieldType.contains("smallint")) {
if (!fieldType.contains("binary") && !fieldType.contains("varbinary")) {
if (fieldType.contains("float")) {
return DbColumnType.FLOAT;
} else {
return !fieldType.contains("double") && !fieldType.contains("real") ? (GaussDbTypeConvert.this.new DateTimeDataTypeHandler()).getDbColumnType(fieldType) : DbColumnType.DOUBLE;
}
} else {
return DbColumnType.BYTE_ARRAY;
}
} else {
return DbColumnType.INTEGER;
}
}else if(fieldType.contains("bigint")){
return DbColumnType.LONG;
}else {
return DbColumnType.INTEGER;
}
} else {
return DbColumnType.BOOLEAN;
}
} else {
return DbColumnType.BIG_DECIMAL;
}
}
}
interface Handler {
DbColumnType getDbColumnType(String fieldType);
}
}
自定义 sql查询,注:这里主要是查询表、字段的信息,可以自定义实现 GaussDbQuery
注意:字段信息涉及到用户,所以条件上需要带上
package com.taia.yms.generate;
import com.baomidou.mybatisplus.generator.config.querys.AbstractDbQuery;
import lombok.Data;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Data
public class GaussDbQuery extends AbstractDbQuery {
//查询需要过滤的字段
private List<String> filterColumns = new ArrayList<>(10);
//查询字段
private List<String> selectColumns = new ArrayList<>(10);
public GaussDbQuery() {
}
public String tablesSql() {
return "SELECT * FROM \n" +
"(SELECT DISTINCT T1.TABLE_NAME as TABLE_NAME,T2.COMMENTS AS TABLE_COMMENT FROM adm_tab_columns T1 \n" +
"LEFT JOIN adm_TAB_COMMENTS T2 ON T1.TABLE_NAME = T2.TABLE_NAME) WHERE 1=1 ";
}
public String tableFieldsSql() {
String baseSql = "SELECT T1.TABLE_NAME,T1.COLUMN_NAME,T2.COMMENTS,T1.DATA_TYPE,CASE WHEN column_name = 'ID' THEN 'PRI' END AS KEY FROM adm_tab_columns T1 " +
" LEFT JOIN adm_TAB_COMMENTS T2 ON (T1.TABLE_NAME = T2.TABLE_NAME AND t1.owner = t2.owner) WHERE t1.owner = 'YES_DEV' and T1.TABLE_NAME = '%s' " ;
StringBuffer sb = new StringBuffer(baseSql);
if(!CollectionUtils.isEmpty(filterColumns)){
String filterColumn = filterColumns.stream().map(v -> "'" + v + "'").collect(Collectors.joining(","));
sb.append("AND COLUMN_name NOT IN(").append(filterColumn).append(")");
}
if(!CollectionUtils.isEmpty(selectColumns)){
String selectColumn = selectColumns.stream().map(v -> "'" + v + "'").collect(Collectors.joining(","));
sb.append("AND COLUMN_name IN(").append(selectColumn).append(")");
}
String orderBySql = " ORDER BY T1.TABLE_NAME,T1.COLUMN_ID";
sb.append(orderBySql);
return sb.toString();
}
public String tableName() {
return "TABLE_NAME";
}
public String tableComment() {
return "TABLE_COMMENT";
}
public String fieldName() {
return "COLUMN_NAME";
}
public String fieldType() {
return "DATA_TYPE";
}
public String fieldComment() {
return "COMMENTS";
}
public String fieldKey() {
return "KEY";
}
}
其他操作公共类 OperateUtils
package com.taia.yms.utils;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
public class OperateUtils {
public static String processName(String name, NamingStrategy strategy) {
return processName( name, strategy, null);
}
public static String processName(String name, NamingStrategy strategy, String[] prefix) {
boolean removePrefix = false;
if (prefix != null && prefix.length != 0) {
removePrefix = true;
}
String propertyName;
if (removePrefix) {
if (strategy == NamingStrategy.underline_to_camel) {
propertyName = NamingStrategy.removePrefixAndCamel(name, prefix);
} else {
propertyName = NamingStrategy.removePrefix(name, prefix);
}
} else if (strategy == NamingStrategy.underline_to_camel) {
propertyName = NamingStrategy.underlineToCamel(name);
} else {
propertyName = name;
}
return propertyName;
}
}
最后就是编写 FTL 模板
在 resources目录下创建 templates目录,然后再下面创建 模板 controller.java.ftl、file.java.ftl、mapper.java.ftl、mapper.xml.ftl、service.java.ftl、serviceImpl.java.ftl、test.java.ftl
下篇文章来讲这一块,给大家提供一些参照