天天看點

mybatis-plus generator自動生成代碼一、概述二、具體實作三、問題是如何解決的四、參考

mybatis-plus generator自動生成代碼

  • 一、概述
  • 二、具體實作
    • 2.1 pom檔案依賴
    • 2.2 核心Config類
    • 2.3 最終效果
  • 三、問題是如何解決的
    • 3.1 解決重複代碼的問題
    • 3.2 解決重新生成時的檔案覆寫問題
    • 3.3 支援自定義模版和自定義參數
  • 四、參考

一、概述

之前一直使用mybatis的自動代碼生成,雖然也能基本滿足要求,但是在實際使用過程中還是存在問題,比如:

  • 自動生成的代碼,每一個mapper,每一個service都會有大量的重複代碼,重複代碼不處理吧看着不舒服,處理的話呢,需要抽象出一個基礎類,在spring環境下,對基礎類以及子類初始化又顯得不夠優雅(參考該項目shuzheng/zheng);
  • 在開發過程中,發現需要修改表結構,每次重新生成的話怎麼指定哪些檔案是需要覆寫的;
  • 如何自定義模版檔案,且支援自定義變量

帶着這些問題,又重新研究了mybatis的好基友mybatis-plus,發現基本上可以完美解決以上面臨的問題。

二、具體實作

2.1 pom檔案依賴

<properties>
        <mybatis-plus.version>3.1.2</mybatis-plus.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
    </parent>

    <dependencies>
        <!-- starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <!-- 資料庫 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>

        <!-- 自動生成代碼 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

        <!-- 工具 -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>25.0-jre</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>
    </dependencies>
           

2.2 核心Config類

@Data
public class GeneratorConfig {
    private static String projectPath = currentProjectPath();

    private DataSourceConfig dataSourceConfig;
    private GlobalConfig globalConfig;
    private PackageConfig packageConfig;
    private TemplateConfig templateConfig;
    private StrategyConfig strategyConfig;
    private InjectionConfig injectionConfig;

    private List<String> includeTableNames;

    public GeneratorConfig() {
        this.dataSourceConfig = new DataSourceConfig();
        this.globalConfig = initGlobalConfig();
        this.packageConfig = new PackageConfig();
        this.strategyConfig = initStrategyConfig();
        this.templateConfig = initTemplateConfig();
        this.injectionConfig = initInjectionConfig();
    }

    /**
     * 全局配置
     */
    private static GlobalConfig initGlobalConfig() {
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setOpen(false);
        gc.setEntityName("%sEntity");
        gc.setServiceName("%sService");
        // 預設允許覆寫檔案
        gc.setFileOverride(true);

        return gc;
    }

    /**
     * 政策配置
     */
    private static StrategyConfig initStrategyConfig() {
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);

        return strategy;
    }

    /**
     * 模版配置
     * 優先掃描本項目中的templates目錄
     */
    private static TemplateConfig initTemplateConfig() {
        TemplateConfig config = new TemplateConfig();
        // 不生成Controller
        config.setController(null);

        return config;
    }

    /**
     * 自定義配置
     */
    private static InjectionConfig initInjectionConfig() {
        // 自定義參數,在模版檔案裡通過${cfg.xxx}引用
        InjectionConfig config = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = this.getMap();
                if (map == null) {
                    map = new HashMap<>();
                    this.setMap(map);
                }

                String datetime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                map.put("datetime", datetime);
            }
        };

        // 如果目前檔案已經存在,則僅允許覆寫Entity
        IFileCreate fileCreate = (configBuilder, fileType, filePath) -> {
            if (new File(filePath).exists()) {
                if (configBuilder.getGlobalConfig().isFileOverride()) {
                    return FileType.ENTITY.equals(fileType);
                } else {
                    return false;
                }
            }

            return true;
        };
        config.setFileCreate(fileCreate);

        return config;
    }

    private static String currentProjectPath() {
        String projectCompletePath = Objects.requireNonNull(ClassLoader.getSystemClassLoader().getResource("")).getPath();
        if (projectCompletePath.startsWith("/")) {
            projectCompletePath = projectCompletePath.replaceFirst("/", "");
        }

        return projectCompletePath.replace("/target/classes/", "");
    }
}
           

2.3 最終效果

mybatis-plus generator自動生成代碼一、概述二、具體實作三、問題是如何解決的四、參考

三、問題是如何解決的

我們來看看文章開頭提出的兩個問題是如何解決的

3.1 解決重複代碼的問題

這個從最終的結果來看,mybatis-plus自動給我們繼承了一個基礎類,完全不用我們自己操心。

3.2 解決重新生成時的檔案覆寫問題

// 如果目前檔案已經存在,則僅允許覆寫Entity
        IFileCreate fileCreate = (configBuilder, fileType, filePath) -> {
            if (new File(filePath).exists()) {
                if (configBuilder.getGlobalConfig().isFileOverride()) {
                    return FileType.ENTITY.equals(fileType);
                } else {
                    return false;
                }
            }

            return true;
        };
        config.setFileCreate(fileCreate);
           

3.3 支援自定義模版和自定義參數

  1. 首先需要在resources目錄下建立目錄templates,然後将模版檔案放進去,需要注意模版檔案必須和TemplateEngine比對。
  2. 在模版檔案裡添加自定義參數,例如datetime,通過${cfg.datetime}的方式
/**
 * Description:
 * ${table.comment!}
 *
 * @author ${author}
 * @since ${cfg.datetime}
 */
           
  1. 在代碼裡配置自定義配置
// 自定義參數,在模版檔案裡通過${cfg.xxx}引用
        InjectionConfig config = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = this.getMap();
                if (map == null) {
                    map = new HashMap<>();
                    this.setMap(map);
                }

                String datetime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                map.put("datetime", datetime);
            }
        };
           

四、參考

  1. 所有代碼都在個人github項目裡mybatis-generator
  2. mybatis-plus官網