【Mybatis-Plus】制作逆向工具
官方文档可参考:
https://baomidou.com/pages/779a6e/#快速入门
工具需要的依赖
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>cn.ymcd</groupId> <artifactId>comm-sample</artifactId> <version>1.0.0</version> </parent> <artifactId>comm-sample-mp-generator</artifactId> <name>comm-sample-mp-generator</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.1.0.7.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.ini4j</groupId> <artifactId>ini4j</artifactId> <version>0.5.4</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <!-- 主类的位置,例如上图文件,主类配置应为: --> <!-- <mainClass>top.nihilwater.App</mainClass> --> <mainClass>cn.ymcd.comm.sample.mp.generator.MainApplication</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
代码部分
代码部分只有一个主类:
package cn.ymcd.comm.sample.mp.generator;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.ini4j.Profile;
import org.ini4j.Wini;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @projectName: comm-sample-mp-generator - 副本
* @author: Cloud9
* @date: 2022年05月31日 13:48
* @version: 1.0
*/
public class MainApplication {
private static Wini windowsConfigIniFile;
private final static String STATUS_TRUE = "true";
private final static String STATUS_FALSE = "false";
private static String commonPath = null;
private static GlobalConfig globalConfig;
private static DataSourceConfig dataSourceConfig;
private static PackageConfig packageConfig;
private static TemplateConfig templateConfig;
private static StrategyConfig strategyConfig;
static {
try {
windowsConfigIniFile = new Wini(new File("config.ini"));
commonPath = windowsConfigIniFile
.get("global-config")
.get("output-directory", "C:\\Users\\Administrator\\Desktop\\Sample");
globalConfig = getGlobalConfig();
dataSourceConfig = getDataSourceConfig();
packageConfig = getPackageConfig();
templateConfig = getTemplateConfig();
strategyConfig = getStrategyConfig();
} catch (IOException e) {
e.printStackTrace();
}
}
private static boolean getBooleanValue(String value) {
return "true".equals(value);
}
private static DateType getDateTypeValue(String value) {
DateType dateType = null;
switch (value) {
case "default":
dateType = DateType.ONLY_DATE;
break;
case "sql-type":
dateType = DateType.SQL_PACK;
break;
case "new-type":
dateType = DateType.TIME_PACK;
break;
}
return dateType;
}
private static IdType getIdTypeValue(String value) {
IdType idType = null;
switch (value) {
case "0":
idType = IdType.AUTO;
break;
case "1":
idType = IdType.NONE;
break;
case "2":
idType = IdType.INPUT;
break;
case "3":
idType = IdType.ID_WORKER;
break;
case "4":
idType = IdType.UUID;
break;
case "5":
idType = IdType.ID_WORKER_STR;
break;
}
return idType;
}
/**
* 全局配置
* @param
* @return com.baomidou.mybatisplus.generator.config.GlobalConfig
* @author Cloud9
* @createTime 2022/5/31 14:33
*
*/
private static GlobalConfig getGlobalConfig() {
Profile.Section section = windowsConfigIniFile.get("global-config");
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(commonPath + "/src/main/java");
globalConfig.setAuthor(section.get("author", "cloud9"));
globalConfig.setOpen(getBooleanValue(section.get("open-after-complete", STATUS_FALSE)));
globalConfig.setFileOverride(getBooleanValue(section.get("overwrite", STATUS_TRUE)));
globalConfig.setActiveRecord(getBooleanValue(section.get("ar-mode", STATUS_FALSE)));
globalConfig.setSwagger2(getBooleanValue(section.get("enable-swagger2", STATUS_FALSE)));
globalConfig.setKotlin(getBooleanValue(section.get("kotlin-mode", STATUS_FALSE)));
// 主键策略
globalConfig.setIdType(getIdTypeValue(section.get("id-type", "0")));
// 日期类型选择
globalConfig.setDateType(getDateTypeValue(section.get("date-type", "default")));
// 文件格式命名
globalConfig.setEntityName(section.get("entity-format", "%sDTO"));
globalConfig.setMapperName(section.get("mapper-format", "%sDAO"));
// globalConfig.setXmlName(section.get("xml-format", "%sMapper"));
// globalConfig.setServiceName(section.get("service-format", "I%sService"));
// globalConfig.setServiceImplName(section.get("service-impl-format", "%sServiceImpl"));
// globalConfig.setControllerName(section.get("controller-format", "%sController"));
return globalConfig;
}
/**
* 获取库名
* @param
* @return java.lang.String
* @author Cloud9
* @createTime 2022/5/31 14:54
*
*/
private static String getSchemaValue() {
Profile.Section section = windowsConfigIniFile.get("db-config");
String connectUrl = section.get("connectUrl");
int i1 = connectUrl.lastIndexOf("/") + 1;
int i2 = connectUrl.lastIndexOf("?");
return connectUrl.substring(i1, i2 == -1 ? connectUrl.length() -1 : i2);
}
/**
* 数据源配置
* @param
* @return com.baomidou.mybatisplus.generator.config.DataSourceConfig
* @author Cloud9
* @createTime 2022/5/31 14:33
*
*/
private static DataSourceConfig getDataSourceConfig() {
Profile.Section section = windowsConfigIniFile.get("db-config");
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(section.get("connectUrl"));
dsc.setSchemaName(getSchemaValue());
dsc.setDriverName(section.get("driverClass"));
dsc.setUsername(section.get("username"));
dsc.setPassword(section.get("password"));
dsc.setDbQuery(new MySqlQuery());
dsc.setDbType(DbType.MYSQL);
dsc.setTypeConvert(new MySqlTypeConvert());
return dsc;
}
/**
* 包配置
* @param
* @return com.baomidou.mybatisplus.generator.config.PackageConfig
* @author Cloud9
* @createTime 2022/5/31 14:54
*
*/
private static PackageConfig getPackageConfig() {
Profile.Section section = windowsConfigIniFile.get("package-config");
PackageConfig pkgConfig = new PackageConfig();
pkgConfig.setParent(section.get("parent"));
pkgConfig.setModuleName(section.get("module", "test"));
pkgConfig.setEntity(section.get("entity", "po"));
pkgConfig.setXml(section.get("xml", "mapper"));
pkgConfig.setMapper(section.get("mapper", "dao"));
pkgConfig.setService(section.get("service", "service"));
pkgConfig.setServiceImpl(section.get("service-impl", "service.impl"));
pkgConfig.setController(section.get("controller", "controller"));
return pkgConfig;
}
/**
* 模板配置
* @param
* @return com.baomidou.mybatisplus.generator.config.TemplateConfig
* @author Cloud9
* @createTime 2022/5/31 14:53
*
*/
private static TemplateConfig getTemplateConfig() {
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
// 指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
templateConfig.setEntity("tpl/entity.java");
templateConfig.setController("tpl/controller.java");
templateConfig.setEntityKt("tpl/entity.kt");
templateConfig.setMapper("tpl/mapper.java");
templateConfig.setService("tpl/service.java");
templateConfig.setServiceImpl("tpl/serviceImpl.java");
return templateConfig;
}
/**
* 注入配置
* @param
* @return com.baomidou.mybatisplus.generator.InjectionConfig
* @author Cloud9
* @createTime 2022/5/31 15:14
*
*/
private static InjectionConfig getInjectionConfig() {
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/tpl/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return
commonPath
+ "/src/main/resources/mapper/"
+ packageConfig.getModuleName()
+ "/"
+ tableInfo.getMapperName()
+ StringPool.DOT_XML;
}
});
/*
* cfg.setFileCreate(new IFileCreate() {
*
* @Override public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) { //
* 判断自定义文件夹是否需要创建 checkDir("调用默认方法创建的目录"); return false; } });
*/
cfg.setFileOutConfigList(focList);
return cfg;
}
/**
* 策略配置
* @param
* @return com.baomidou.mybatisplus.generator.config.StrategyConfig
* @author Cloud9
* @createTime 2022/5/31 15:14
*
*/
private static StrategyConfig getStrategyConfig() {
Profile.Section section = windowsConfigIniFile.get("strategy-config");
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
//strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
strategyConfig.setEntityLombokModel(getBooleanValue(section.get("lombok-model", STATUS_TRUE)));
strategyConfig.setRestControllerStyle(getBooleanValue(section.get("rest-controller", STATUS_TRUE)));
strategyConfig.setSuperControllerClass(section.get("super-controller", "cn.ymcd.comm.base.BaseController"));
strategyConfig.setSuperServiceImplClass(section.get("super-service-impl", "com.baomidou.mybatisplus.extension.service.impl.ServiceImpl"));
strategyConfig.setInclude(includesHandle((section.get("includes").split(","))));
//strategy.setSuperEntityColumns("id");
strategyConfig.setControllerMappingHyphenStyle(getBooleanValue(section.get("hyphen-style", STATUS_TRUE)));
strategyConfig.setTablePrefix(packageConfig.getModuleName() + "_");
return strategyConfig;
}
private static String[] includesHandle(String[] includes) {
for (int i = 0; i < includes.length; i++) includes[i] = includes[i].trim();
return includes;
}
private static AutoGenerator getAutoGenerator() {
AutoGenerator mpg = new AutoGenerator();
mpg.setGlobalConfig(globalConfig);
mpg.setDataSource(dataSourceConfig);
mpg.setPackageInfo(packageConfig);
mpg.setCfg(getInjectionConfig());
mpg.setStrategy(strategyConfig);
mpg.setTemplate(templateConfig);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
return mpg;
}
public static void main(String[] args) {
getAutoGenerator().execute();
}
}
还是走配置文件设置参数:
config.ini 放在项目的目录下面,不是src里面
[global-config] # 输出目录 output-directory = C:\Users\Administrator\Desktop\AISW-TEST # 创建者 author = dzz # 完成后打开目录 open-after-complete = true # 覆写输出 overwrite = true # 开启Swagger2注解 enable-swagger2 = false # ActiveRecord 模式 ar-mode = false # 转换科特林代码 kotlin-mode = false # 生成的时间类型,(default, sql-type, new-type) date-type = default # 主键生成策略 (0 1 2 3 4 5) id-type = 0 # 实体类文件命名格式 entity-format = %sDTO # 映射接口文件命名格式 mapper-format = %sDAO # 映射接口文件命名格式 xml-format = %sMapper # 服务接口文件命名格式 service-format = I%sService # 服务实现文件命名格式 service-impl-format = %sServiceImpl # 控制器文件命名格式 controller-format = %sController [db-config] # 连接配置参数 connectUrl = jdbc:mysql://192.168.209.11:3306/ymcd_aisw?useSSL=false&serverTimeZone=GMT driverClass = com.mysql.jdbc.Driver username = root password = 123456 [package-config] # 包名配置 parent = cn.cloud9.sample module = test entity = po mapper = dao xml = mapper service = service service-impl = service.impl controller = controller [strategy-config] # 开启Lombok注解? lombok-model = true # 是否@RestController rest-controller = true # 指定生成的表名,多个用逗号进行分隔 includes = aisw_netplace, aisw_netplace_sync_log # 继承的控制器类名 super-controller = cn.ymcd.comm.base.BaseController # 继承的服务实现类名 super-service-impl = cn.ymcd.comm.base.BaseService # 接口地址 驼峰转至连字符 hyphen-style = true
模板部分
因为设置模板文件路径,所以是采用自定义模板来输出
templateConfig.setXml(null);
templateConfig.setEntity("tpl/entity.java");
templateConfig.setController("tpl/controller.java");
templateConfig.setEntityKt("tpl/entity.kt");
templateConfig.setMapper("tpl/mapper.java");
templateConfig.setService("tpl/service.java");
templateConfig.setServiceImpl("tpl/serviceImpl.java");

Controller.java.ftl
package ${package.Controller};
import org.springframework.web.bind.annotation.RequestMapping;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
/**
* ${table.name!} ${table.comment!} 前端控制器
*
* @projectName:
* @author:${author}
* @date:${date}
* @version 1.0
*/
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("${r'${api.path}'}<#if package.ModuleName??>/${package.ModuleName}</#if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>
}
</#if>
entity.java.ftl
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
</#if>
/**
* ${table.name!} ${table.comment!} 实体类
*
* @projectName:
* @author:${author}
* @date:${date}
* @version 1.0
*/
<#if entityLombokModel>
@Data
<#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
<#else>
@EqualsAndHashCode(callSuper = false)
</#if>
@Accessors(chain = true)
</#if>
<#if table.convert>
@TableName("${table.name}")
</#if>
<#if swagger2>
@ApiModel(value="${entity}对象", description="${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#else>
public class ${entity} implements Serializable {
</#if>
<#if entitySerialVersionUID>
private static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.keyFlag>
<#assign keyPropertyName="${field.propertyName}"/>
</#if>
<#if field.comment!?length gt 0>
<#if swagger2>
@ApiModelProperty(value = "${field.comment}")
<#else>
/**
* ${field.comment}
*/
</#if>
</#if>
<#if field.keyFlag>
<#-- 主键 -->
<#if field.keyIdentityFlag>
@TableId(value = "${field.name}", type = IdType.AUTO)
<#elseif idType??>
@TableId(value = "${field.name}", type = IdType.${idType})
<#elseif field.convert>
@TableId("${field.name}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- ----- 存在字段填充设置 ----->
<#if field.convert>
@TableField(value = "${field.name}", fill = FieldFill.${field.fill})
<#else>
@TableField(fill = FieldFill.${field.fill})
</#if>
<#elseif field.convert>
@TableField("${field.name}")
</#if>
<#-- 乐观锁注解 -->
<#if (versionFieldName!"") == field.name>
@Version
</#if>
<#-- 逻辑删除注解 -->
<#if (logicDeleteFieldName!"") == field.name>
@TableLogic
</#if>
private ${field.propertyType} ${field.propertyName};
</#list>
<#------------ END 字段循环遍历 ---------->
<#if !entityLombokModel>
<#list table.fields as field>
<#if field.propertyType == "boolean">
<#assign getprefix="is"/>
<#else>
<#assign getprefix="get"/>
</#if>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
<#if entityBuilderModel>
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
<#else>
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
</#if>
this.${field.propertyName} = ${field.propertyName};
<#if entityBuilderModel>
return this;
</#if>
}
</#list>
</#if>
<#if entityColumnConstant>
<#list table.fields as field>
public static final String ${field.name?upper_case} = "${field.name}";
</#list>
</#if>
<#if activeRecord>
@Override
protected Serializable pkVal() {
<#if keyPropertyName??>
return this.${keyPropertyName};
<#else>
return null;
</#if>
}
</#if>
<#if !entityLombokModel>
@Override
public String toString() {
return "${entity}{" +
<#list table.fields as field>
<#if field_index==0>
"${field.propertyName}=" + ${field.propertyName} +
<#else>
", ${field.propertyName}=" + ${field.propertyName} +
</#if>
</#list>
"}";
}
</#if>
}
mapper.java.ftl
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* ${table.name!} ${table.comment!} Mapper 接口
*
* @projectName:
* @author:${author}
* @date:${date}
* @version 1.0
*/
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}
</#if>
service.java.ftl
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* ${table.name!} ${table.comment!} 服务类
*
* @projectName:
* @author:${author}
* @date:${date}
* @version 1.0
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
}
</#if>
mapper.xml.ftl
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
<#if enableCache>
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
</#if>
<#if baseResultMap>
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
<#list table.fields as field>
<#if field.keyFlag><#--生成主键排在第一位-->
<id column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
<#list table.commonFields as field><#--生成公共字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#list>
<#list table.fields as field>
<#if !field.keyFlag><#--生成普通字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
</resultMap>
</#if>
<#if baseColumnList>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<#list table.commonFields as field>
${field.name},
</#list>
${table.fieldNames}
</sql>
</#if>
</mapper>
serviceImpl.java.ftl
package ${package.ServiceImpl};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
/**
* ${table.name!} ${table.comment!} 服务实现类
*
* @projectName:
* @author:${author}
* @date:${date}
* @version 1.0
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
}
</#if>
打包之后,自己新建目录做一个工具包

Start.cmd 只是方便启动Jar包
java -jar comm-sample-mp-generator-1.0.0.jar
如果要保留执行日志可以
java -jar comm-sample-mp-generator-1.0.0.jar > excute.log
还需要有一个Java的环境变量存在

浙公网安备 33010602011771号