liding
4 天以前 79828b3a3174ceccf3445a9364f708ecf1712c8f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package com.ruoyi;
 
import com.baomidou.mybatisplus.annotation.FieldFill;
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.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
 
/**
 * MyBatis-Plus 代码生成器
 * 功能:根据数据库表结构自动生成Entity、Mapper、Service、Controller等代码
 * 修复:解决Freemarker模板中generateService变量缺失的问题
 */
@SpringBootApplication
public class PlusCodeGenerator {
 
    // 数据库配置
    private static final String DB_URL = "jdbc:postgresql://lunor.cn:5431/ruoyi-java";
    private static final String DB_USERNAME = "test";
    private static final String DB_PASSWORD = "chj123456";
 
    // 项目基础配置
    private static final String BASE_PACKAGE = "com.ruoyi";
    private static final String MODULE_NAME = "basic"; // 模块名
 
    public static void main(String[] args) {
        String projectPath = System.getProperty("user.dir"); // 获取项目根路径
        String path = "basic-server"; // 模块名称
        String table = "supply"; // 表名,多个表逗号隔开
 
        // 代码输出路径配置
        String outputBasePath = Paths.get(projectPath, path, "src", "main", "java").toString();
        String outputResourcePath = Paths.get(projectPath, path, "src", "main", "resources", "mapper").toString();
 
        // 代码生成核心配置
        FastAutoGenerator.create(DB_URL, DB_USERNAME, DB_PASSWORD)
                .globalConfig(builder -> {
                    builder.author("ld") // 作者信息
                            .outputDir(outputBasePath) // 代码输出目录
                            .dateType(DateType.ONLY_DATE) // 日期类型
                            .commentDate("yyyy-MM-dd") // 注释日期格式
                            .disableOpenDir(); // 禁止自动打开输出目录
                })
                .packageConfig(builder -> {
                    builder.parent(BASE_PACKAGE) // 基础包名
                            .moduleName(MODULE_NAME) // 模块名(根据具体修改)
                            .entity("entity") // Entity包名
                            .mapper("mapper") // Mapper包名
                            .service("service") // Service包名
                            .serviceImpl("service.impl") // Service实现类包名
                            .controller("controller") // Controller包名
                            .pathInfo(Collections.singletonMap(
                                    OutputFile.xml,
                                    outputResourcePath // Mapper XML输出路径
                            ));
                })
                .strategyConfig(builder -> {
                    builder.addInclude(table) // 要生成的表名
                            .addTablePrefix("t_", "sys_") // 过滤表前缀
 
                            // 实体类配置
                            .entityBuilder()
                            .superClass("com.ruoyi.common.core.domain.BaseEntity") // 继承基类
                            .addSuperEntityColumns("create_by", "create_time", "update_by", "update_time") // 排除基类字段
                            .enableLombok() // 启用Lombok
                            .naming(NamingStrategy.underline_to_camel) // 表名转驼峰
                            .columnNaming(NamingStrategy.underline_to_camel) // 列名转驼峰
                            .enableFileOverride() // 允许覆盖文件
                            .logicDeleteColumnName("deleted") // 逻辑删除字段
                            .addTableFills(
                                    // 自动填充配置
                                    new Column("create_by", FieldFill.INSERT), // 创建人,插入时填充
                                    new Column("update_by", FieldFill.INSERT_UPDATE), // 更新人,插入和更新时填充
                                    new Column("create_time", FieldFill.INSERT), // 创建时间,插入时填充
                                    new Column("update_time", FieldFill.INSERT_UPDATE) // 更新时间,插入和更新时填充
                            )
                            .idType(IdType.AUTO) // 主键策略
                            .enableTableFieldAnnotation() // 启用字段注解
 
                            // 控制器配置
                            .controllerBuilder()
                            .enableFileOverride() // 允许覆盖
                            .enableRestStyle() // 生成RESTful风格控制器
 
                            // Service配置
                            .serviceBuilder()
                            .formatServiceFileName("%sService") // Service接口命名格式
                            .enableFileOverride() // 允许覆盖
                            .formatServiceImplFileName("%sServiceImpl") // Service实现类命名格式
                            .enableFileOverride() // 允许覆盖
 
                            // Mapper配置
                            .mapperBuilder()
                            .enableFileOverride() // 允许覆盖
                            .enableMapperAnnotation() // 启用@Mapper注解
                            .enableBaseResultMap() // 启用基础ResultMap
                            .enableBaseColumnList() // 启用基础ColumnList
                            .formatMapperFileName("%sMapper") // Mapper接口命名格式
                            .formatXmlFileName("%sMapper") // Mapper XML命名格式
                            .enableFileOverride(); // 允许覆盖
                })
                // 配置自定义模板
                .templateConfig(builder -> {
                    builder
                            .entity("/templates/entity.java") // 实体类模板
                            .xml("/templates/mapper.xml") // Mapper XML模板
                            .controller("/templates/controller.java") // 控制器模板
                            .serviceImpl("/templates/serviceImpl.java"); // Service实现类模板
                })
                // 注入模板变量
                .injectionConfig(builder -> {
                    Map<String, Object> customMap = new HashMap<>();
                    customMap.put("superEntityColumns", Arrays.asList(
                            "create_by", "create_time", "update_by", "update_time"
                    )); // 基类字段
                    customMap.put("idType", "AUTO"); // 主键类型
                    customMap.put("superEntityClass", "com.ruoyi.common.core.domain.BaseEntity"); // 基类全路径
                    customMap.put("author", "ruoyi"); // 作者信息
                    customMap.put("packageName", BASE_PACKAGE + "." + MODULE_NAME); // 包名
                    customMap.put("tableName", table); // 表名
 
                    // 新增:解决Freemarker模板中generateService变量缺失的问题
                    // 控制Service实现类是否实现Service接口
                    boolean generateService = true;
                    customMap.put("generateService", generateService);
 
                    builder.customMap(customMap);
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker模板引擎
                .execute(); // 执行代码生成
 
        // 后处理:修复实体类的完全限定名问题
        try {
            Path entityPath = Paths.get(outputBasePath, "com/ruoyi/basic/entity/Test.java");
            if (Files.exists(entityPath)) {
                String content = Files.readString(entityPath);
                content = content.replace(
                        "extends com.ruoyi.common.core.domain.BaseEntity",
                        "extends BaseEntity"
                ); // 简化基类引用
                Files.writeString(entityPath, content);
            }
        } catch (IOException e) {
            System.err.println("⚠️ 修复实体类失败: " + e.getMessage());
        }
 
        System.out.println("✅ 代码生成完成!文件已输出到:" + outputBasePath);
    }
}