diff --git a/carp-support/carp-generator/pom.xml b/carp-support/carp-generator/pom.xml new file mode 100644 index 00000000..38466e4f --- /dev/null +++ b/carp-support/carp-generator/pom.xml @@ -0,0 +1,60 @@ + + + + + 4.0.0 + + cn.sliew + carp-support + 0.0.12-SNAPSHOT + ../pom.xml + + carp-generator + + + + ${project.parent.groupId} + carp-framework-mybatis + + + + com.baomidou + mybatis-plus-generator + + + org.apache.velocity + velocity-engine-core + + + + + ${project.artifactId} + + + ${basedir}/src/main/resources + + custom-entity.java.vm + + true + + + + + \ No newline at end of file diff --git a/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/MySQLGenerator.java b/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/MySQLGenerator.java new file mode 100644 index 00000000..6cece3a6 --- /dev/null +++ b/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/MySQLGenerator.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.generator; + +import cn.sliew.carp.support.generator.helper.MybatisPlusHelper; + +public class MySQLGenerator { + + private final static String AUTHOR = "wangqi"; + private final static String URL = "jdbc:mysql://127.0.0.1:3306/carp"; + private final static String USERNAME = "root"; + private final static String PASSWORD = "123456"; //NOSONAR + private static final String BASE_PACKAGE = "cn.sliew"; + private static final String MODULE = "carp"; + + /** + * just add table names here and run the {@link #main(String[])} method. + */ + private static final String[] TABLES = {"carp_sec_application"}; + + public static void main(String[] args) { + MybatisPlusHelper.generatorMySQL(URL, USERNAME, PASSWORD, AUTHOR, BASE_PACKAGE, MODULE, TABLES); + } +} diff --git a/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/PostgreSQLGenerator.java b/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/PostgreSQLGenerator.java new file mode 100644 index 00000000..ebea6112 --- /dev/null +++ b/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/PostgreSQLGenerator.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.generator; + +import cn.sliew.carp.support.generator.helper.MybatisPlusHelper; + +public class PostgreSQLGenerator { + + private final static String AUTHOR = "wangqi"; + private final static String URL = "jdbc:postgresql://localhost:5432/dw"; + private final static String USERNAME = "root"; + private final static String PASSWORD = "123456"; //NOSONAR + private static final String BASE_PACKAGE = "cn.sliew"; + private static final String MODULE = "carp"; + + /** + * just add table names here and run the {@link #main(String[])} method. + */ + private final static String SCHEMA = "dwd"; + private static final String[] TABLES = {"dwd_ds_table_1"}; + + public static void main(String[] args) { + MybatisPlusHelper.generatorPostgreSQL(URL, USERNAME, PASSWORD, SCHEMA, AUTHOR, BASE_PACKAGE, MODULE, TABLES); + } +} diff --git a/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/helper/MybatisPlusHelper.java b/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/helper/MybatisPlusHelper.java new file mode 100644 index 00000000..c795cc04 --- /dev/null +++ b/carp-support/carp-generator/src/main/java/cn/sliew/carp/support/generator/helper/MybatisPlusHelper.java @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.generator.helper; + +import cn.sliew.carp.framework.mybatis.entity.BaseAuditDO; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.generator.FastAutoGenerator; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.builder.Controller; +import com.baomidou.mybatisplus.generator.config.builder.Entity; +import com.baomidou.mybatisplus.generator.config.builder.Mapper; +import com.baomidou.mybatisplus.generator.config.builder.Service; +import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert; +import com.baomidou.mybatisplus.generator.config.converts.PostgreSqlTypeConvert; +import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery; +import com.baomidou.mybatisplus.generator.config.querys.PostgreSqlQuery; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import com.baomidou.mybatisplus.generator.fill.Column; +import com.baomidou.mybatisplus.generator.fill.Property; +import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler; +import com.baomidou.mybatisplus.generator.keywords.PostgreSqlKeyWordsHandler; + +public class MybatisPlusHelper { + + private static final String TABLE_PREFIX = ""; + + public static void generatorMySQL(String jdbcUrl, String jdbcUserName, String jdbcPassword, String author, String basePackage, String moduleName, String[] tables) { + doGenerator(mysqlDataSourceConfig(jdbcUrl, jdbcUserName, jdbcPassword), author, basePackage, moduleName, tables); + } + + public static void generatorPostgreSQL(String jdbcUrl, String jdbcUserName, String jdbcPassword, String schema, String author, String basePackage, String moduleName, String[] tables) { + doGenerator(postgresqlDataSourceConfig(jdbcUrl, jdbcUserName, jdbcPassword, schema), author, basePackage, moduleName, tables); + } + + public static void doGenerator(DataSourceConfig.Builder dataSourceConfigBuilder, String author, String basePackage, String moduleName, String[] tables) { + //自动生成配置 + FastAutoGenerator generator = FastAutoGenerator.create(dataSourceConfigBuilder) + .globalConfig(builder -> globalConfig(builder, author)) + .packageConfig(builder -> packageConfig(builder, basePackage, moduleName)) + .templateConfig(MybatisPlusHelper::templateConfig) + .strategyConfig(builder -> strategyConfig(builder, tables)) + .injectionConfig(MybatisPlusHelper::injectionConfig); + generator.execute(); + } + + /** + * 数据源配置 + * + * @return DataSourceConfig + */ + private static DataSourceConfig.Builder mysqlDataSourceConfig(String jdbcUrl, String jdbcUserName, String password) { + return new DataSourceConfig.Builder(jdbcUrl, jdbcUserName, password) + .dbQuery(new MySqlQuery()) + .typeConvert(new MySqlTypeConvert()) + .keyWordsHandler(new MySqlKeyWordsHandler()); + } + + /** + * 数据源配置 + * + * @return DataSourceConfig + */ + private static DataSourceConfig.Builder postgresqlDataSourceConfig(String jdbcUrl, String jdbcUserName, String password, String schema) { + return new DataSourceConfig.Builder(jdbcUrl, jdbcUserName, password) + .schema(schema) + .dbQuery(new PostgreSqlQuery()) + .typeConvert(new PostgreSqlTypeConvert()) + .keyWordsHandler(new PostgreSqlKeyWordsHandler()); + } + + /** + * 全局配置 + * + * @return GlobalConfig + */ + private static void globalConfig(GlobalConfig.Builder builder, String author) { + builder + .outputDir(System.getProperty("user.dir") + + "/carp-support/carp-generator/src/main/java/") + .author(author) + .enableSpringdoc() + .dateType(DateType.ONLY_DATE) + .commentDate("yyyy-MM-dd"); + } + + /** + * 包配置 + * + * @return PackageConfig + */ + private static void packageConfig(PackageConfig.Builder builder, String basePackage, String moduleName) { + builder.parent(basePackage) + .moduleName(moduleName) + .entity("dao.entity") + .service("service") + .serviceImpl("service.impl") + .mapper("dao.mapper") + .xml("dao.mapper") + .controller("api.controller"); +// .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "/Users/wangqi/Downloads/generator")); + } + + private static void templateConfig(TemplateConfig.Builder builder) { + // 设置 null 避免对应的类生成 + // 修改 entity 模板,使用自定义的 + builder.controller(null) + .service(null) + .serviceImpl(null) + .entity("/custom-entity.java.vm"); + } + + /** + * 策略配置 + * + * @return StrategyConfig + */ + private static void strategyConfig(StrategyConfig.Builder builder, String[] tables) { + builder.enableCapitalMode() + .enableSkipView() + .disableSqlFilter() + .addInclude(tables) + .addTablePrefix(TABLE_PREFIX); + + Entity.Builder entityBuilder = builder.entityBuilder(); + entityBuilder.superClass(BaseAuditDO.class) + .enableLombok() + .enableTableFieldAnnotation() + .enableRemoveIsPrefix() + .naming(NamingStrategy.underline_to_camel) + .columnNaming(NamingStrategy.underline_to_camel) + .addSuperEntityColumns("id", "creator", "created_time", "editor", "update_time") + .idType(IdType.AUTO) + .addTableFills(new Column("create_time", FieldFill.INSERT)) + .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE)) + .formatFileName("%s"); + + Mapper.Builder mapperBuilder = builder.mapperBuilder(); + mapperBuilder.superClass(BaseMapper.class) + .enableMapperAnnotation() + .enableBaseResultMap() + .enableBaseColumnList() + .formatMapperFileName("%sMapper") + .formatXmlFileName("%sMapper"); + + Service.Builder serviceBuilder = builder.serviceBuilder(); + serviceBuilder.formatServiceFileName("%sService") + .formatServiceImplFileName("%sServiceImp") + .build(); + + + Controller.Builder controllerBuilder = builder.controllerBuilder(); + controllerBuilder.enableHyphenStyle() + .enableRestStyle() + .formatFileName("%sController") + .build(); + + } + + /** + * 自定义配置 + * + * @return InjectionConfig + */ + private static void injectionConfig(InjectionConfig.Builder builder) { + + } +} diff --git a/carp-support/carp-generator/src/main/resources/custom-entity.java.vm b/carp-support/carp-generator/src/main/resources/custom-entity.java.vm new file mode 100644 index 00000000..90c28625 --- /dev/null +++ b/carp-support/carp-generator/src/main/resources/custom-entity.java.vm @@ -0,0 +1,155 @@ +package ${package.Entity}; + +#foreach($pkg in ${table.importPackages}) +import ${pkg}; +#end +#if(${springdoc}) +import io.swagger.v3.oas.annotations.media.Schema; +#elseif(${swagger}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end +#if(${entityLombokModel}) +import lombok.Data; +#if(${chainModel}) +import lombok.experimental.Accessors; +#end +#end + +/** + * $!{table.comment} + */ +#if(${entityLombokModel}) +@Data + #if(${chainModel}) +@Accessors(chain = true) + #end +#end +#if(${table.convert}) +@TableName("${schemaName}${table.name}") +#end +#if(${springdoc}) +@Schema(name = "${entity}", description = "$!{table.comment}") +#elseif(${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(${springdoc}) + @Schema(description = "${field.comment}") + #elseif(${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/carp-support/pom.xml b/carp-support/pom.xml index 5f996fd7..517ac7a4 100644 --- a/carp-support/pom.xml +++ b/carp-support/pom.xml @@ -29,4 +29,8 @@ carp-support pom + + carp-generator + + \ No newline at end of file