小書MybatisPlus第7篇-程式碼生成器的原理精講及使用方法

字母哥部落格發表於2020-07-24

本文是本系列文章的第七篇,前6篇訪問地址如下:

一、程式碼生成器的基礎實現原理

相信大部分的開發者都使用過或者聽說過“模板引擎”,它可以幫我們實現檢視與資料的分離,快速開發檢視頁面,並將模板整合結果用於在瀏覽器顯示。其核心實現原理就是:HTML模板頁面 + 頁面資料 = 輸出結果。頁面檢視輸出的過程就是通過模板引擎實現的。

freemarker模板引擎

程式碼生成器的實現原理與模板引擎實現頁面渲染的邏輯幾乎是一致的,除了下面的幾個區別:

  • 所謂模板:就是某語言的程式碼 + 模板引擎語法的佔位符,該佔位符用來資料天換。所以程式碼生成器的模板檔案不再專指HTML頁面模板檔案,可以是任何型別的程式碼檔案。
  • 模板引擎的輸出結果在專案中是輸出給瀏覽器進行頁面渲染的,但是對於程式碼生成器而言,模板引擎的輸出結果是儲存到磁碟檔案。

程式碼自動生成

二、如何編寫模板檔案

要編寫模板檔案,首先我們要知道正常的程式碼待如何書寫。比如下面的POJO程式碼:

程式碼自動生成

上面的POJO程式碼寫成Freemarker模板檔案,就是下面的樣子:

package ${package.Entity};

<#list table.importPackages as pkg>
import ${pkg};
</#list>

<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;
</#if>

/**
 * <p>
 * ${table.comment!}
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
<#if entityLombokModel>
@Data
    <#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
    <#else>
@EqualsAndHashCode(callSuper = false)
    </#if>
</#if>
public class ${entity} extends Model<${entity}> {

<#list table.fields as field>
    private ${field.propertyType} ${field.propertyName};
</#list>

Mybatis Plus 程式碼生成的模板檔案:https://gitee.com/baomidou/mybatis-plus/tree/3.0/mybatis-plus-generator/src/main/resources/templates

三、資料從哪裡來?

有了模板檔案,我們想通過模板引擎生成程式碼,下面的一個問題就是資料從哪裡來?有了資料我們才能生成程式碼

  • 從配置中來,比如:package路徑等一些靜態化不經常變化的資訊,一個專案生成的程式碼存放的包路徑通常不會經常變化。
  • 從資料庫中來,比如:實體類名稱、實體類欄位名稱、實體類欄位型別等資訊。類似於逆向工程,通過資料庫表名、欄位名、欄位型別等資訊生成實體資訊。

3.1.以MySQL的INFORMATION_SCHEMA資訊獲取為例

我們的程式碼自動生成是針對資料庫操作,所以首先要了解資料庫表的結構

SELECT  column_name,data_type,is_nullable,character_maximum_length,column_comment
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_name='kpi_task' 
AND table_schema='home'
ORDER BY ordinal_position

如上圖SQL查詢的是home庫,kpi_task表的資訊,如下:

程式碼自動生成

  • column_name作為表的欄位可以生成實體類的成員變數引數名稱(通常是駝峰標識規則)
  • data_type,is_nullable,character_maximum_length可用於生成校驗規則。
  • 註釋可以用於生成column_comment

四、Mybatis Plus程式碼生成器的使用

如果上面的程式碼生成器實現原理你都看懂了,下面的這些配置你也就不難理解了。

4.1.新增依賴

  • 新增 程式碼生成器 依賴
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.2</version>
</dependency>
  • 新增 模板引擎 依賴,MyBatis-Plus 支援 Velocity(預設)、Freemarker、Beetl,使用者可以選擇自己熟悉的模板引擎。

    Velocity(預設):

    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.2</version>
    </dependency>
    

    Freemarker:

    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.30</version>
    </dependency>
    

    Beetl:

    <dependency>
        <groupId>com.ibeetl</groupId>
        <artifactId>beetl</artifactId>
        <version>3.1.8.RELEASE</version>
    </dependency>
    

注意!如果您選擇了非預設引擎,需要在 AutoGenerator 中 設定模板引擎。

AutoGenerator generator = new AutoGenerator();

// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());

// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());

// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());

// other config
...

4.2.程式碼生成配置

AutoGenerator 是 MyBatis-Plus 的程式碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模組的程式碼,極大的提升了開發效率。

執行下面的這個測試用例,Mybatis Plus就可以幫助我們實現以上各層的程式碼生成到對應的package路徑下面

public class CodeGenerator {
 
    @Test
    public void startGenerator() {
        //1、全域性配置
        GlobalConfig config = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        config.setActiveRecord(true)//開啟AR模式
                .setAuthor("zimug")//設定作者
                .setOutputDir(projectPath + "/src/main/java")//生成路徑(一般在此專案的src/main/java下)
                .setFileOverride(true)//第二次生成會把第一次生成的覆蓋掉
                .setOpen(true)//生成完畢後是否自動開啟輸出目錄
                //.setSwagger2(true)//實體屬性 Swagger2 註解
                //.setIdType(IdType.AUTO)//主鍵策略
                .setServiceName("%sService")//生成的service介面名字首字母是否為I,這樣設定就沒有I
                .setBaseResultMap(true)//生成resultMap
                .setBaseColumnList(true);//在xml中生成基礎列
        //2、資料來源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)//資料庫型別
                .setDriverName("com.mysql.jdbc.Driver")
                .setUrl("jdbc:mysql://localhost:3306/zimug")
                .setUsername("root")
                .setPassword("zimug3456");
        //3、策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true)//開啟全域性大寫命名
                .setNaming(NamingStrategy.underline_to_camel)//表名對映到實體的命名策略(下劃線到駝峰)
                //表欄位對映屬性名策略(未指定按naming)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                //.setTablePrefix("tb_")//表名字首
                //.setSuperEntityClass("你自己的父類實體,沒有就不用設定!")
                //.setSuperEntityColumns("id");//寫於父類中的公共欄位
                //.setSuperControllerClass("自定義繼承的Controller類全稱,帶包名,沒有就不用設定!")
                .setRestControllerStyle(true) //生成 @RestController 控制器
                .setEntityLombokModel(true)//使用lombok
                .setInclude("sys_user","sys_role");//逆向工程使用的表
        //4、包名策略配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.zimug.example")//設定包名的parent
                .setMapper("mapper")
                .setService("service")
                .setController("controller")
                .setEntity("entity")
                .setXml("mapper");//設定xml檔案的目錄
        //5、整合配置
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig);
        //6、執行
        autoGenerator.execute();
    }
}

歡迎關注我的部落格,裡面有很多精品合集

  • 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格

覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力! 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。

相關文章