diff --git a/src/test/java/io/github/xxyopen/novel/generator/Generator.java b/src/test/java/io/github/xxyopen/novel/generator/Generator.java new file mode 100644 index 0000000..da0c4c6 --- /dev/null +++ b/src/test/java/io/github/xxyopen/novel/generator/Generator.java @@ -0,0 +1,87 @@ +package io.github.xxyopen.novel.generator; + + +import com.baomidou.mybatisplus.generator.FastAutoGenerator; +import com.baomidou.mybatisplus.generator.config.DataSourceConfig; +import com.baomidou.mybatisplus.generator.config.OutputFile; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; + +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * 代码生成器 + * + * @author xiongxiaoyang + * @date 2022/5/11 + */ +public class Generator { + + private static final String USERNAME = System.getenv().get("USER"); + + /** + * 项目信息 + */ + private static final String PROJECT_PATH = System.getProperty("user.dir"); + private static final String JAVA_PATH = "/src/main/java"; + private static final String RESOURCE_PATH = "/src/main/resources"; + private static final String BASE_PACKAGE = "io.github.xxyopen.novel"; + + /** + * 数据库信息 + */ + private static final String DATABASE_IP = "127.0.0.1"; + private static final String DATABASE_PORT = "3306"; + private static final String DATABASE_NAME = "novel"; + private static final String DATABASE_USERNAME = "root"; + private static final String DATABASE_PASSWORD = "test123456"; + + /** + * 生成的表名,多个用英文逗号分隔,所有用 all 表示 + */ + private static final String GEN_TABLES = "all"; + + + /** + * 执行 run + */ + public static void main(String[] args) throws SQLException { + + FastAutoGenerator.create(String.format("jdbc:mysql://%s:%s/%s?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai", DATABASE_IP, DATABASE_PORT, DATABASE_NAME), DATABASE_USERNAME, DATABASE_PASSWORD) + .globalConfig(builder -> { + builder.author(USERNAME) // 设置作者 + .fileOverride() + // kotlin + //.enableSwagger() // 开启 swagger 模式 + .fileOverride() // 覆盖已生成文件 + .commentDate("yyyy/MM/dd") + .outputDir(PROJECT_PATH + JAVA_PATH); // 指定输出目录 + + }) + .packageConfig(builder -> builder.parent(BASE_PACKAGE) // 设置父包名 + .entity("dao.entity") + .service("service") + .serviceImpl("service.impl") + .mapper("dao.mapper") + .controller("controller.front") + .pathInfo(Collections.singletonMap(OutputFile.mapperXml, PROJECT_PATH + RESOURCE_PATH + "/mapper"))) + .strategyConfig(builder -> builder.addInclude(getTables(GEN_TABLES)) // 设置需要生成的表名 + .controllerBuilder() + .enableRestStyle() + .serviceBuilder() + .formatServiceFileName("%sService") + ) // 开启生成@RestController 控制器 + //.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板 + .execute(); + + } + + // 处理 all 情况 + protected static List getTables(String tables) { + return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(",")); + } + +} diff --git a/src/test/resources/templates/controller.java.vm b/src/test/resources/templates/controller.java.vm new file mode 100644 index 0000000..5216721 --- /dev/null +++ b/src/test/resources/templates/controller.java.vm @@ -0,0 +1,38 @@ +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; +#end +#if(${superControllerClassPackage}) +import ${superControllerClassPackage}; +#end + +/** + *

+ * $!{table.comment} 控制器 + *

+ * + * @author ${author} + * @date ${date} + */ +#if(${restControllerStyle}) +@RestController +#else +@Controller +#end +@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end") +#if(${kotlin}) +class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end + +#else +#if(${superControllerClass}) +public class ${table.controllerName} extends ${superControllerClass} { +#else +public class ${table.controllerName} { +#end + +} +#end diff --git a/src/test/resources/templates/entity.java.vm b/src/test/resources/templates/entity.java.vm new file mode 100644 index 0000000..77179a4 --- /dev/null +++ b/src/test/resources/templates/entity.java.vm @@ -0,0 +1,157 @@ +package ${package.Entity}; + +#foreach($pkg in ${table.importPackages}) +import ${pkg}; +#end +#if(${swagger}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end +#if(${entityLombokModel}) +import lombok.Getter; +import lombok.Setter; +#if(${chainModel}) +import lombok.experimental.Accessors; +#end +#end + +/** + *

+ * $!{table.comment} + *

+ * + * @author ${author} + * @date ${date} + */ +#if(${entityLombokModel}) +@Getter +@Setter + #if(${chainModel}) +@Accessors(chain = true) + #end +#end +#if(${table.convert}) +@TableName("${schemaName}${table.name}") +#end +#if(${swagger}) +@ApiModel(value = "${entity}对象", description = "$!{table.comment}") +#end +#if(${superEntityClass}) +public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { +#elseif(${activeRecord}) +public class ${entity} extends Model<${entity}> { +#elseif(${entitySerialVersionUID}) +public class ${entity} implements Serializable { +#else +public class ${entity} { +#end +#if(${entitySerialVersionUID}) + + private static final long serialVersionUID = 1L; +#end +## ---------- BEGIN 字段循环遍历 ---------- +#foreach($field in ${table.fields}) + +#if(${field.keyFlag}) +#set($keyPropertyName=${field.propertyName}) +#end +#if("$!field.comment" != "") + #if(${swagger}) + @ApiModelProperty("${field.comment}") + #else + /** + * ${field.comment} + */ + #end +#end +#if(${field.keyFlag}) +## 主键 + #if(${field.keyIdentityFlag}) + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + #elseif(!$null.isNull(${idType}) && "$!idType" != "") + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + #elseif(${field.convert}) + @TableId("${field.annotationColumnName}") + #end +## 普通字段 +#elseif(${field.fill}) +## ----- 存在字段填充设置 ----- + #if(${field.convert}) + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + #else + @TableField(fill = FieldFill.${field.fill}) + #end +#elseif(${field.convert}) + @TableField("${field.annotationColumnName}") +#end +## 乐观锁注解 +#if(${field.versionField}) + @Version +#end +## 逻辑删除注解 +#if(${field.logicDeleteField}) + @TableLogic +#end + private ${field.propertyType} ${field.propertyName}; +#end +## ---------- END 字段循环遍历 ---------- + +#if(!${entityLombokModel}) +#foreach($field in ${table.fields}) + #if(${field.propertyType.equals("boolean")}) + #set($getprefix="is") + #else + #set($getprefix="get") + #end + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + #if(${chainModel}) + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + #else + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + #end + this.${field.propertyName} = ${field.propertyName}; + #if(${chainModel}) + return this; + #end + } +#end +## --foreach end--- +#end +## --end of #if(!${entityLombokModel})-- + +#if(${entityColumnConstant}) + #foreach($field in ${table.fields}) + public static final String ${field.name.toUpperCase()} = "${field.name}"; + + #end +#end +#if(${activeRecord}) + @Override + public Serializable pkVal() { + #if(${keyPropertyName}) + return this.${keyPropertyName}; + #else + return null; + #end + } + +#end +#if(!${entityLombokModel}) + @Override + public String toString() { + return "${entity}{" + + #foreach($field in ${table.fields}) + #if($!{foreach.index}==0) + "${field.propertyName}=" + ${field.propertyName} + + #else + ", ${field.propertyName}=" + ${field.propertyName} + + #end + #end + "}"; + } +#end +} diff --git a/src/test/resources/templates/entity.kt.vm b/src/test/resources/templates/entity.kt.vm new file mode 100644 index 0000000..c7f3663 --- /dev/null +++ b/src/test/resources/templates/entity.kt.vm @@ -0,0 +1,116 @@ +package ${package.Entity}; + +#foreach($pkg in ${table.importPackages}) +import ${pkg}; +#end +#if(${swagger}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end + +/** + *

+ * $!{table.comment} + *

+ * + * @author ${author} + * @date ${date} + */ +#if(${table.convert}) +@TableName("${schemaName}${table.name}") +#end +#if(${swagger}) +@ApiModel(value = "${entity}对象", description = "$!{table.comment}") +#end +#if(${superEntityClass}) +class ${entity} : ${superEntityClass}#if(${activeRecord})<${entity}>#end() { +#elseif(${activeRecord}) +class ${entity} : Model<${entity}>() { +#elseif(${entitySerialVersionUID}) +class ${entity} : Serializable { +#else +class ${entity} { +#end + +## ---------- BEGIN 字段循环遍历 ---------- +#foreach($field in ${table.fields}) +#if(${field.keyFlag}) +#set($keyPropertyName=${field.propertyName}) +#end +#if("$!field.comment" != "") + #if(${swagger}) + @ApiModelProperty(value = "${field.comment}") + #else + /** + * ${field.comment} + */ + #end +#end +#if(${field.keyFlag}) +## 主键 +#if(${field.keyIdentityFlag}) + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) +#elseif(!$null.isNull(${idType}) && "$!idType" != "") + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) +#elseif(${field.convert}) + @TableId("${field.annotationColumnName}") +#end +## 普通字段 +#elseif(${field.fill}) +## ----- 存在字段填充设置 ----- +#if(${field.convert}) + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) +#else + @TableField(fill = FieldFill.${field.fill}) +#end +#elseif(${field.convert}) + @TableField("${field.annotationColumnName}") +#end +## 乐观锁注解 +#if(${field.versionField}) + @Version +#end +## 逻辑删除注解 +#if(${field.logicDeleteField}) + @TableLogic +#end + #if(${field.propertyType} == "Integer") + var ${field.propertyName}: Int? = null + #else + var ${field.propertyName}: ${field.propertyType}? = null + #end + +#end +## ---------- END 字段循环遍历 ---------- +#if(${entityColumnConstant}) + companion object { +#foreach($field in ${table.fields}) + + const val ${field.name.toUpperCase()} : String = "${field.name}" + +#end + } + +#end +#if(${activeRecord}) + override fun pkVal(): Serializable? { +#if(${keyPropertyName}) + return ${keyPropertyName} +#else + return null +#end + } + +#end + override fun toString(): String { + return "${entity}{" + +#foreach($field in ${table.fields}) +#if($!{foreach.index}==0) + "${field.propertyName}=" + ${field.propertyName} + +#else + ", ${field.propertyName}=" + ${field.propertyName} + +#end +#end + "}" + } +} diff --git a/src/test/resources/templates/mapper.java.vm b/src/test/resources/templates/mapper.java.vm new file mode 100644 index 0000000..c2cb924 --- /dev/null +++ b/src/test/resources/templates/mapper.java.vm @@ -0,0 +1,26 @@ +package ${package.Mapper}; + +import ${package.Entity}.${entity}; +import ${superMapperClassPackage}; +#if(${mapperAnnotationClass}) +import ${mapperAnnotationClass.name}; +#end + +/** + *

+ * $!{table.comment} Mapper 接口 + *

+ * + * @author ${author} + * @date ${date} + */ +#if(${mapperAnnotationClass}) +@${mapperAnnotationClass.simpleName} +#end +#if(${kotlin}) +interface ${table.mapperName} : ${superMapperClass}<${entity}> +#else +public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { + +} +#end diff --git a/src/test/resources/templates/mapper.xml.vm b/src/test/resources/templates/mapper.xml.vm new file mode 100644 index 0000000..b0909e8 --- /dev/null +++ b/src/test/resources/templates/mapper.xml.vm @@ -0,0 +1,39 @@ + + + + +#if(${enableCache}) + + + +#end +#if(${baseResultMap}) + + +#foreach($field in ${table.fields}) +#if(${field.keyFlag})##生成主键排在第一位 + +#end +#end +#foreach($field in ${table.commonFields})##生成公共字段 + +#end +#foreach($field in ${table.fields}) +#if(!${field.keyFlag})##生成普通字段 + +#end +#end + + +#end +#if(${baseColumnList}) + + +#foreach($field in ${table.commonFields}) + ${field.columnName}, +#end + ${table.fieldNames} + + +#end + diff --git a/src/test/resources/templates/service.java.vm b/src/test/resources/templates/service.java.vm new file mode 100644 index 0000000..2efffb0 --- /dev/null +++ b/src/test/resources/templates/service.java.vm @@ -0,0 +1,20 @@ +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; + +/** + *

+ * $!{table.comment} 服务类 + *

+ * + * @author ${author} + * @date ${date} + */ +#if(${kotlin}) +interface ${table.serviceName} : ${superServiceClass}<${entity}> +#else +public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { + +} +#end diff --git a/src/test/resources/templates/serviceImpl.java.vm b/src/test/resources/templates/serviceImpl.java.vm new file mode 100644 index 0000000..a5ed504 --- /dev/null +++ b/src/test/resources/templates/serviceImpl.java.vm @@ -0,0 +1,26 @@ +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.comment} 服务实现类 + *

+ * + * @author ${author} + * @since ${date} + */ +@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} { + +} +#end