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