easygen通用代碼生成框架[開源]


什么東東

用過mybatis的同學都知道,手工寫mapper和xml是一件很痛苦的事兒,幸好官方提供了Mybatis-Generator,但是這家伙生成的東西不開放不方便修改,而且項目中的代碼生成需求不只是數據訪問層,比如說view、service、controller,這些地方到處充斥着重復代碼,有什么好辦法了,反正我是見識少,只能自己動手了。

設計思路

簡單點,設計的思路簡單點,只有簡單別人才好上手。

  • 1.利用模板引擎加載模型,渲染模板,生成文件。
  • 2.模型由模型構建器加載,要內置mysql元數據作為模型,支持自定義其他模型構建器
  • 3.模型和模板文件要分離,這樣模型可以重用到其他模板
  • 4.模型和模板文件是一對多的關系,方面根據一個表生成po、mapper、service
  • 5.支持一個模型批量生成,如數據庫表這種,不能每個表對應一個模型吧

先不要想那么多,就這些吧

使用方式設計

很多同學一上來就寫代碼,最后根據功能設計使用方式,我更傾向於先把使用方式設計好,俗話說好的開始是成功的一半。

  1. 代碼生成方式簡單點,那就 java -jar xxxx.jar吧,然后在ohmyzsh里配置一下alias就爽了。
  2. 配置文件用json 簡單好維護,文件名和路徑默認,支持修改。
  3. 發布包提供樣板,方便學習和使用。

好了,先YY一個配置文件,看看:

{
  "modelBuilders": [
    {
      "name": "mysql", //模型構建器名稱要
      "type": "db:mysql", //構建器類型
      "configPath": "modelBuilders/mysql.json" //數據庫配置
    }
  ],
  "templates": [
    {
      "name": "beanClass",
      "modelBuilderName": "mysql", //關聯的模型構建器name
      "templateFilename": "beanClass.ftl",
      "outputPath": "output/bean"
    }
  ]
}

恩就這樣,是不是有點暈,我解釋一下:

  • 1.首先我們的框架加載配置文件。
  • 2.然后根據配置文件中的modelBuilders加載指定type的模型構建器
  • 3.然后將configPath指定的配置文件傳給模型構建器,用於構建數據模型
  • 4.框架根據配置文件中的templates中的每一個元素的modelBuilderName屬性去關聯已經構建好的模型構建器。
  • 5.然后框架使用模型構建器構建Model,並根據templateFilename指定的模板文件進行渲染(使用freemarker)
  • 6.輸出文件到outputPath

最終效果

github: https://github.com/BigMaMonkey/easygen

其實框架的代碼很簡單,重點還是設計好使用方式,簡單並可擴展,其實過程中還需要一些其他特性:

  • 基於freemarker的模板語法,上手簡單
  • 內置mysql、json模型構建器,並支持自定義
  • 支持生成指定表、去掉表前綴、轉換大小寫等
  • 支持模型與模板的一對多關系(模型與模板的分離)
  • 支持List類型的模型,批量生成。
  • 支持自定義文件名生成規則
  • 支持自定義輸出路徑
  • 支持模板自定義參數

以下示例演示了應用於mybatis的代碼生成使用。

1.首先下載easygen發布包 下載

解壓后,包含以下幾部分:

  • easygen-1.0-SNAPSHOT.jar:這是easygen主程序,負責讀取配置文件並生成代碼
  • config.json:這是easy主配置文件
  • modelBuildrs:這里存放的是模型構建器的配置文件
  • templates:這是里存放的是模板文件
  • lib:這里存放的是easygen引用的第三方jar包

2.編寫主配置文件

目錄下的config.json為主配置文件, 發布包已經給出了一個比較完整的配置,包括型構建器配置和模板配置,包括生成bean、mapperclass、mapperxml、serviceInterface、serviceImpl、view、dbtojson(生成數據庫元數據)很簡單自己看配置和代碼就行了。。。

{
  "modelBuilders": [
    {
      "name": "mysql", //構建器名稱要唯一
      "type": "db:mysql", //構建器類型目前只支持mysql和json兩種
      "configPath": "modelBuilders/mysql.json" //數據庫配置和生成表指定
    },
    {
      "name": "json",
      "type": "json",
      "configPath": "modelBuilders/data.json" //與mysql構建器不同的是,這里直接是模型數據。
    },
    {
      "name": "http",
      "type": "custom", //自定義的構建器
      "configPath": "modelBuilders/xxx.json", //這個json反序列化類型需要在IModelBuilder的泛型參數中指出。
      "modelBuilderClassName": "org.BigMaMonkey.XXX.XXX" //自定義的構建器需要實現類,實現IModelBuilder借口
    }
  ],
  "templates": [
    {
      "name": "mapperXml",
      "modelBuilderName": "json", //關聯的構建器名稱,不是類型
      "templateFilename": "data.ftl", //ftl模板文件
      "outputPath": "output/data", //輸出目錄,會自動遞歸創建目錄。
      "outputFilenameRule": "data_{name}.xml", //輸出文件名規則,{}內變量為模型的字段field
      "options": {} //自定義模板參數,可以在模板中使用,請自由發揮。
    },
    {
      "name": "mapperXml",
      "modelBuilderName": "mysql",
      "templateFilename": "mapperXml.ftl",
      "outputPath": "output/mapperXml",
      "outputFilenameRule": "{upperCaseName}Mapper.xml",
      "options": {
        "mapperns": "org.bigmonkey.robot.mapper",
        "pons": "org.bigmonkey.robot.entity.po"
      }
    },
    {
      "name": "beanClass",
      "modelBuilderName": "mysql",
      "templateFilename": "beanClass.ftl",
      "outputPath": "output/bean",
      "outputFilenameRule": "{upperCaseName}.java",
      "options": {
        "pons": "org.bigmonkey.robot.entity.po"
      }
    },
    {
      "name": "mapperClass",
      "modelBuilderName": "mysql",
      "templateFilename": "mapperClass.ftl",
      "outputPath": "output/mapper",
      "outputFilenameRule": "{upperCaseName}Mapper.java",
      "options": {
        "pons": "org.bigmonkey.robot.entity.po",
        "mpns": "org.bigmonkey.robot.mapper"
      }
    },
    {
      "name": "serviceInterface",
      "modelBuilderName": "mysql",
      "templateFilename": "serviceInterface.ftl",
      "outputPath": "output/service",
      "outputFilenameRule": "I{simpleName}Service.java",
      "options": {
        "pons": "org.bigmonkey.robot.entity.po",
        "itns": "org.bigmonkey.robot.service"
      }
    },
    {
      "name": "serviceImpl",
      "modelBuilderName": "mysql",
      "templateFilename": "serviceImpl.ftl",
      "outputPath": "output/service",
      "outputFilenameRule": "{simpleName}ServiceImpl.java",
      "options": {
        "pons": "org.bigmonkey.robot.entity.po",
        "imns": "org.bigmonkey.robot.service.impl"
      }
    },
    {
      "name": "view",
      "modelBuilderName": "mysql",
      "templateFilename": "view.ftl",
      "outputPath": "output/view",
      "outputFilenameRule": "{name}view.vue",
      "options": {}
    },
    {
      "name": "db-to-json",
      "modelBuilderName": "mysql",
      "templateFilename": "dbtojson.ftl",
      "outputPath": "output/json",
      "outputFilenameRule": "{name}.json",
      "options": {}
    }
  ]
}

3.編寫模板
其實模板的編寫很簡單,你只需要掌握freemarker的ftl語法,以及基本的json知識就可以了。
這里只講解mybatis內置構建器的使用

3.1.首先是構建器配置

{
  "name": "mysql", //構建器名稱要唯一
  "type": "db:mysql", //構建器類型目前只支持mysql和json兩種
  "configPath": "modelBuilders/mysql.json" //數據庫配置和生成表指定
}

type中db:mysql指定使用內置的mysql構建器,configPath指定構建器的配置文件,配置如下:

{
  "dbUrl": "jdbc:mysql://localhost:3306/device_manage",
  "driverClassName": "com.mysql.jdbc.Driver",
  "username": "root",
  "password": "root",
  "tables": "sys_user,pub_dict" //用,分割指定生成的表名,也可以留空表示生成所有表
}

3.2.需要給出的是內置mysql構建器的模型結構,你才能在ftl中使用

{
  "name": "sys_user", //原始表名
  "upperCaseName": "SYS_User", //前綴大寫+首字符大寫表名,用於創建PO、Mapper等
  "simpleName": "User", // 去掉前綴的表名,目前只支持_分割的表名,如sys_user
  "pkgs": [
    "java.util.Date" // 字段類型對應的Java包,import到java文件
  ],
  "fields": [
    {
      "name": "name", //原始字段名
      "upperCaseName": "Name", //首字母大寫字段名
      "dataType": "12", // 字段類型值,對應 java.sql.Types中的枚舉值
      "typeName": "VARCHAR", //字段數據庫類型,其他類型參見源碼:TableField.java
      "columnSize": "32", //字段大小
      "columnType": {
        "javaType": "String", //對應的java類型
        "pkg": null  //基礎類型為null,不需要import
      }
    }
  ],
  "primaryKey": {
    //同field中的元素屬性
  }
}

在ftl中模型的跟是model,例如你要在ftl中輸出一個表名${model.name}, 又或者是主鍵的名稱${model.primaryKey.name}

如果你在模板配置中設置了自定義模板參數options,請這樣使用它${options.xxx}

通過在outputFilenameRule中使用{XXX}可以引用model中根屬性,來自定義輸出文件名,如{upperCaseName}Mapper.java

4.最后使用方式相當簡單:

java -jar easygen-1.0-SNAPSHOT.jar 

當然你也可以把代碼的執行集成到你自己的項目或工具:

public class App {
    public static void main(String[] args) {
        GeneratorManager generatorManager = new GeneratorManager();
        try {
            generatorManager.Start();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM