3 changed files with 358 additions and 0 deletions
@ -0,0 +1,242 @@ |
|||||
|
package com.youlai.boot.codegen; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||
|
import com.baomidou.mybatisplus.generator.FastAutoGenerator; |
||||
|
import com.baomidou.mybatisplus.generator.config.OutputFile; |
||||
|
import com.baomidou.mybatisplus.generator.config.po.TableField; |
||||
|
import com.baomidou.mybatisplus.generator.config.rules.DateType; |
||||
|
import com.baomidou.mybatisplus.generator.config.rules.IColumnType; |
||||
|
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; |
||||
|
import com.baomidou.mybatisplus.generator.type.ITypeConvertHandler; |
||||
|
import com.baomidou.mybatisplus.generator.type.TypeRegistry; |
||||
|
import org.springframework.util.CollectionUtils; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
public class MyBatisPlusGenerator { |
||||
|
|
||||
|
/** |
||||
|
* 表配置(核心) |
||||
|
*/ |
||||
|
static class TableConfig { |
||||
|
private final String tableName; |
||||
|
private final IdType idType; |
||||
|
private final String module; |
||||
|
|
||||
|
public TableConfig(String tableName, IdType idType, String module) { |
||||
|
this.tableName = tableName; |
||||
|
this.idType = idType; |
||||
|
this.module = module; |
||||
|
} |
||||
|
|
||||
|
public String getTableName() { |
||||
|
return tableName; |
||||
|
} |
||||
|
|
||||
|
public IdType getIdType() { |
||||
|
return idType; |
||||
|
} |
||||
|
|
||||
|
public String getModule() { |
||||
|
return module; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 自定义类型转换 |
||||
|
*/ |
||||
|
public static class MyCustomTypeConvertHandler implements ITypeConvertHandler { |
||||
|
@Override |
||||
|
public IColumnType convert(com.baomidou.mybatisplus.generator.config.GlobalConfig globalConfig, |
||||
|
TypeRegistry typeRegistry, |
||||
|
TableField.MetaInfo metaInfo) { |
||||
|
|
||||
|
String columnType = metaInfo.getTypeName(); |
||||
|
String columnName = metaInfo.getColumnName(); |
||||
|
|
||||
|
System.out.println(">>> [字段处理] column: " + columnName + |
||||
|
", columnType: " + columnType); |
||||
|
|
||||
|
if (columnType != null && |
||||
|
(columnType.toLowerCase().contains("geometry") |
||||
|
|| columnType.toLowerCase().contains("point"))) { |
||||
|
|
||||
|
System.out.println(">>> 命中地理类型字段,使用 Point"); |
||||
|
|
||||
|
return new IColumnType() { |
||||
|
@Override |
||||
|
public String getType() { |
||||
|
return "Point"; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getPkg() { |
||||
|
return "org.locationtech.jts.geom"; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
return typeRegistry.getColumnType(metaInfo); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
|
||||
|
String url = "jdbc:mysql://rm-bp11k2zm2fr7864428o.mysql.rds.aliyuncs.com:3306/stray_animals_back?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai"; |
||||
|
String username = "zhc"; |
||||
|
String password = "Youqu48bnb1"; |
||||
|
|
||||
|
/** |
||||
|
* 表维度配置(你只需要改这里🔥) |
||||
|
*/ |
||||
|
List<TableConfig> tableConfigs = Arrays.asList( |
||||
|
|
||||
|
new TableConfig("mini_stray_animal", IdType.AUTO, "mini") |
||||
|
// ,new TableConfig("mini_stray_animal", IdType.AUTO, "mini")
|
||||
|
|
||||
|
// ,new TableConfig("mini_stray_animal", IdType.INPUT, "minitest")
|
||||
|
//
|
||||
|
// ,new TableConfig("mini_stray_animal", IdType.NONE, "minitest2")
|
||||
|
|
||||
|
); |
||||
|
|
||||
|
// 按 module + idType 分组(企业级写法)
|
||||
|
Map<String, Map<IdType, List<String>>> grouped = new HashMap<>(); |
||||
|
|
||||
|
for (TableConfig config : tableConfigs) { |
||||
|
grouped |
||||
|
.computeIfAbsent(config.getModule(), k -> new HashMap<>()) |
||||
|
.computeIfAbsent(config.getIdType(), k -> new ArrayList<>()) |
||||
|
.add(config.getTableName()); |
||||
|
} |
||||
|
|
||||
|
// 分批生成
|
||||
|
for (Map.Entry<String, Map<IdType, List<String>>> moduleEntry : grouped.entrySet()) { |
||||
|
|
||||
|
String module = moduleEntry.getKey(); |
||||
|
|
||||
|
for (Map.Entry<IdType, List<String>> idEntry : moduleEntry.getValue().entrySet()) { |
||||
|
|
||||
|
generate(url, username, password, |
||||
|
idEntry.getValue(), |
||||
|
idEntry.getKey(), |
||||
|
module); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 核心生成方法 |
||||
|
*/ |
||||
|
private static void generate(String url, |
||||
|
String username, |
||||
|
String password, |
||||
|
List<String> tables, |
||||
|
IdType idType, |
||||
|
String moduleName) { |
||||
|
|
||||
|
if (CollectionUtils.isEmpty(tables)) { |
||||
|
System.out.println(">>> [跳过] tables为空"); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
System.out.println(">>> 开始生成:module=" + moduleName + " tables=" + tables); |
||||
|
|
||||
|
FastAutoGenerator.create(url, username, password) |
||||
|
|
||||
|
// 全局配置
|
||||
|
.globalConfig(builder -> builder |
||||
|
.author("jwy") |
||||
|
.disableOpenDir() |
||||
|
.dateType(DateType.TIME_PACK) |
||||
|
.commentDate("") |
||||
|
) |
||||
|
|
||||
|
// 数据源
|
||||
|
.dataSourceConfig(builder -> builder |
||||
|
.schema("stray_animals_back") |
||||
|
.typeConvertHandler(new MyCustomTypeConvertHandler()) |
||||
|
) |
||||
|
|
||||
|
// 包 + 路径(动态模块)
|
||||
|
.packageConfig(builder -> builder |
||||
|
.parent("com.youlai.boot") |
||||
|
.moduleName(moduleName) |
||||
|
.entity("model.entity") |
||||
|
.mapper("mapper") |
||||
|
.xml("mapper") |
||||
|
.pathInfo(getPathInfo(moduleName)) |
||||
|
) |
||||
|
|
||||
|
// 策略
|
||||
|
.strategyConfig(builder -> { |
||||
|
|
||||
|
builder.addInclude(tables); |
||||
|
|
||||
|
// entity
|
||||
|
builder.entityBuilder() |
||||
|
.enableFileOverride() |
||||
|
.enableLombok() |
||||
|
.enableTableFieldAnnotation() |
||||
|
.naming(NamingStrategy.underline_to_camel) |
||||
|
.columnNaming(NamingStrategy.underline_to_camel) |
||||
|
.enableChainModel() |
||||
|
.enableRemoveIsPrefix() |
||||
|
.logicDeleteColumnName("deleted") |
||||
|
.idType(idType); |
||||
|
|
||||
|
// mapper
|
||||
|
builder.mapperBuilder() |
||||
|
.enableFileOverride() |
||||
|
.enableBaseResultMap() |
||||
|
.enableBaseColumnList() |
||||
|
.formatMapperFileName("%sMapper") |
||||
|
.formatXmlFileName("%sMapper"); |
||||
|
|
||||
|
// 不生成 service / controller(彻底关闭)
|
||||
|
builder.serviceBuilder().disable(); |
||||
|
builder.controllerBuilder().disable(); |
||||
|
}) |
||||
|
|
||||
|
// 模板(只保留 entity)
|
||||
|
.templateConfig(builder -> builder |
||||
|
.entity("templates/codegen/ftl/entity.java") |
||||
|
.disable( |
||||
|
com.baomidou.mybatisplus.generator.config.TemplateType.SERVICE, |
||||
|
com.baomidou.mybatisplus.generator.config.TemplateType.SERVICE_IMPL, |
||||
|
com.baomidou.mybatisplus.generator.config.TemplateType.CONTROLLER |
||||
|
) |
||||
|
) |
||||
|
|
||||
|
.execute(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 动态路径(按模块) |
||||
|
*/ |
||||
|
private static Map<OutputFile, String> getPathInfo(String moduleName) { |
||||
|
|
||||
|
String projectRoot = System.getProperty("user.dir"); |
||||
|
|
||||
|
Map<OutputFile, String> pathInfo = new HashMap<>(); |
||||
|
|
||||
|
String base = projectRoot + "/src/main/java/com/youlai/boot/" + moduleName; |
||||
|
|
||||
|
pathInfo.put(OutputFile.entity, base + "/model/entity"); |
||||
|
pathInfo.put(OutputFile.mapper, base + "/mapper"); |
||||
|
|
||||
|
pathInfo.put(OutputFile.xml, |
||||
|
projectRoot + "/src/main/resources/mapper/" + moduleName + "/"); |
||||
|
|
||||
|
// pathInfo.put(OutputFile.service,
|
||||
|
// projectRoot + "/src/main/java/com/youlai/boot/mini/service");
|
||||
|
//
|
||||
|
// pathInfo.put(OutputFile.serviceImpl,
|
||||
|
// projectRoot + "/src/main/java/com/youlai/boot/mini/service/impl");
|
||||
|
//
|
||||
|
// pathInfo.put(OutputFile.controller,
|
||||
|
// projectRoot + "/src/main/java/com/youlai/boot/mini/controller");
|
||||
|
|
||||
|
return pathInfo; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,90 @@ |
|||||
|
package ${package.Entity}; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.*; |
||||
|
import io.swagger.v3.oas.annotations.media.Schema; |
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
import lombok.ToString; |
||||
|
import lombok.experimental.Accessors; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
<#-- 日期导入 --> |
||||
|
<#list table.fields as field> |
||||
|
<#if field.propertyType == "LocalDate" || field.propertyType == "LocalDateTime"> |
||||
|
import java.util.Date; |
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
<#break> |
||||
|
</#if> |
||||
|
</#list> |
||||
|
<#-- 导入 org.locationtech.jts.geom.Point 类型 --> |
||||
|
<#list table.fields as field> |
||||
|
<#if field.propertyType == "Point"> |
||||
|
import org.locationtech.jts.geom.Point; |
||||
|
import com.pet.map.back.handler.PointTypeHandler; |
||||
|
<#break> |
||||
|
</#if> |
||||
|
</#list> |
||||
|
<#-- BigDecimal 导入 --> |
||||
|
<#list table.fields as field> |
||||
|
<#if field.propertyType == "BigDecimal"> |
||||
|
import java.math.BigDecimal; |
||||
|
<#break> |
||||
|
</#if> |
||||
|
</#list> |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
@ToString |
||||
|
@Accessors(chain = true) |
||||
|
@TableName("${table.name}") |
||||
|
@Schema(description = "${table.comment!}") |
||||
|
public class ${entity} implements Serializable { |
||||
|
|
||||
|
<#-- 主键字段 --> |
||||
|
<#assign hasPk = false> |
||||
|
<#list table.fields as field> |
||||
|
<#if field.keyFlag> |
||||
|
<#assign hasPk = true> |
||||
|
@TableId(value = "${field.name}", type = IdType.${idType!"ASSIGN_ID"}) |
||||
|
@Schema(description = "${field.comment!}") |
||||
|
<#if field.propertyType == "LocalDate"> |
||||
|
JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
||||
|
private Date ${field.propertyName}; |
||||
|
<#elseif field.propertyType == "LocalDateTime"> |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
||||
|
private Date ${field.propertyName}; |
||||
|
<#else> |
||||
|
private ${field.propertyType} ${field.propertyName}; |
||||
|
</#if> |
||||
|
|
||||
|
</#if> |
||||
|
</#list> |
||||
|
|
||||
|
<#-- 普通字段 --> |
||||
|
<#list table.fields as field> |
||||
|
<#if !field.keyFlag> |
||||
|
<#if field.propertyType == "Point"> |
||||
|
@TableField(value = "${field.name}", typeHandler = PointTypeHandler.class) |
||||
|
<#else> |
||||
|
@TableField("${field.name}") |
||||
|
</#if> |
||||
|
@Schema(description = "${field.comment!}") |
||||
|
<#if field.propertyType == "LocalDate"> |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
||||
|
private Date ${field.propertyName}; |
||||
|
<#elseif field.propertyType == "LocalDateTime"> |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
||||
|
private Date ${field.propertyName}; |
||||
|
<#else> |
||||
|
private ${field.propertyType} ${field.propertyName}; |
||||
|
</#if> |
||||
|
|
||||
|
</#if> |
||||
|
</#list> |
||||
|
|
||||
|
<#-- 无主键表的额外处理 --> |
||||
|
<#if !hasPk> |
||||
|
<#-- 在这里可以添加无主键表特有的方法或注释 --> |
||||
|
<#-- 例如,可能需要提供手动主键生成策略或者修改操作方法 --> |
||||
|
</#if> |
||||
|
} |
||||
Loading…
Reference in new issue