Java Web 模板程式碼生成器的設計與實現
起因
專案中需要根據資料庫表寫很多Meta、Dao、Service程式碼,其中很多程式碼都是重複而繁瑣的。因此如果有一個模板程式碼的生成器,就可以一定程度提高開發效率。
目標
可配置生成Java Web專案中Dao、Meta、Service層模板程式碼的生成器。
程式碼框架
mvn archetype:generate -DgroupId=com.zju -DartifactId=JavaWebCodeGenerator -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false -DarchetypeCatalog=internal
設計思路
專案參考Mybatis generator生成程式碼的過程,具體步驟分為以下5步。
邏輯步驟
- 解析命令列
- 解析配置檔案
- 獲取資料表資訊
- 生成配置資訊
- 生成檔案
程式碼設計
命令解析類 ShellRunner
該類負責解析命令列的命令,解析配置檔案並封裝所需的資料給程式碼生成類。
可解析命令有-configfile
:指定配置檔案所在路徑和-overwrite
:是否重寫目標檔案。
配置檔案的配置項有:
//Java SQL 驅動所在路徑(暫未使用) private static final String CLASS_PATH_ENTRY = "class.path.entry"; //Java 驅動型別(暫未使用) private static final String DRIVER_CLASS = "driver.class"; //資料庫地址 private static final String CONNECTION_URL = "connection.url"; //資料庫使用者名稱 private static final String USER_ID = "user.id"; //資料庫密碼 private static final String USER_PASSWORD = "user.password"; //模型生成地址 private static final String JAVA_MODEL_PACKAGE = "java.model.package"; //SQL生成地址 private static final String SQL_MAPPING_PACKAGE = "sql.mapping.package"; //專案地址 private static final String PROJECT = "project"; //資料表名 private static final String TABLE_NAME = "table.name"; //模型名稱 private static final String DOMAIN_OBJECT_NAME = "domain.object.name";
程式碼生成類 CodeGenerator
該類負責連線資料庫,查詢資料表的表資訊,將SQL型別對映成Java型別並封裝所需的資料給檔案生成類。
Class.forName(configuration.getDriverClass()); //獲取資料庫連線 Connection connection = DriverManager.getConnection(configuration.getConnectionURL(), configuration.getUserId(), configuration.getPassword()); DatabaseMetaData databaseMetaData = connection.getMetaData(); //獲取表結構資訊 ResultSet rs = databaseMetaData.getColumns("", "", configuration.getTableName(), "%");
通過以上幾行程式碼,rs變數中已經獲得目標資料表的表資訊。
databaseMetaData.getColumns
方法的實質是執行了SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME="tableName"
語句。
在結果集中,後續處理大致需要以下表資訊列。
欄位 | 描述 |
---|---|
DATA_TYPE | 資料型別 |
COLUMN_SIZE | 資料長度 |
COLUMN_NANE | 列名 |
NULLABLE | 是否允許非空 |
DECIMAL_DIGITS | 小數位數 |
REMARKS | 備註 |
COLUMN_DEF | 預設值 |
最後通過JavaTypeResolver
中的型別對映(Map<Integer, JdbcTypeInformation> typeMap
)和StringUtils
中的駝峰命名轉換(getCamelCaseString
)將SQL資訊轉換成Java資訊。
檔案生成類 FileGenerator
該類通過FreeMarker模板引擎組合資料成目的碼檔案。
主邏輯如下:
/** * @param configuration 封裝的配置資訊 * @param columns 封裝的資料表列資訊 * @throws IOException * @throws TemplateException */ public static void writeFile(Configuration configuration, List<TableColumn> columns) throws IOException, TemplateException { File r=new File(""); //測試環境獲取專案根目錄路徑 //String path=Class.class.getClass().getResource("/").getPath(); //Jar包獲取根目錄路徑 String path=r.getAbsolutePath(); //System.out.println("path:"+path); Configuration cfg = new Configuration(); cfg.setDirectoryForTemplateLoading(new File(path + "/ftl")); //需要資料夾絕對路徑 cfg.setDefaultEncoding("UTF-8"); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); Map root = new HashMap(); root.put("configuration", configuration); root.put("columnList", columns); writeSingleFile(cfg, root, "DaoImpl.ftl", configuration.getProjectPath(), configuration.getSqlMappingPackage().replace(".", "/"), configuration.getDomainObjectName(), "DaoImpl.java",configuration.getOverwrite()); writeSingleFile(cfg, root, "Dao.ftl", configuration.getProjectPath(), configuration.getSqlMappingPackage().replace(".", "/"), configuration.getDomainObjectName(), "Dao.java",configuration.getOverwrite()); writeSingleFile(cfg, root, "Meta.ftl", configuration.getProjectPath(), configuration.getJavaModelPackage().replace(".", "/"), configuration.getDomainObjectName(), ".java",configuration.getOverwrite()); }
注意
在測試中,Class.class.getClass().getResource("/").getPath();
該方法可以獲取專案根目錄,但是在測試生成的Jar包時,該方法時效。因此在生成Jar包前需要把該行修改成new File("").getAbsolutePath();
獲取生成路徑。
專案結構
配置檔案範例
generatorConfig.properties
class.path.entry=src/test/resources/mysql-connector-java-5.1.38.jar driver.class=com.mysql.jdbc.Driver connection.url=jdbc:mysql://localhost:3307/work user.id= user.password= java.model.package=com.model sql.mapping.package=com.dao project=src table.name=holiday domain.object.name=Holiday
執行命令範例
java -jar JavaWebCodeGenerator.jar -configfile generatorConfig.properties -overwrite
例項演示
原始碼
https://github.com/TedHacker/PracticeArea/tree/master/JavaWebCodeGenerator
相關文章
- java 程式碼生成器設計方案Java
- go模板-程式碼生成器Go
- 談響應式web設計程式碼實現Web
- JAVA實現編寫平臺程式碼生成器Java
- 現代c++與模板超程式設計C++程式設計
- 設計模式 - java程式碼實現單例模式設計模式Java單例
- Web 魔方模擬器的設計與實現Web
- Mybatis自動程式碼生成器的實現MyBatis
- Mybatis-plus程式碼生成器的實現MyBatis
- OpenAPI生成器中實現自定義模板API
- 低程式碼之光!輕量級 GUI 的設計與實現GUI
- 手把手實現一個web程式碼模板快速生成CLI工具Web
- Java 併發程式設計:ThreadLocal 的使用及其原始碼實現Java程式設計thread原始碼
- Getty – Java NIO 框架設計與實現Java框架
- Web應用隱形後門的設計與實現Web
- JAVA實現網路程式設計之併發程式設計Java程式設計
- JNPF低程式碼開發框架程式碼 生成器設計框架
- Java實驗六: Java流式程式設計與網路程式設計(頭歌)Java程式設計
- Laravel 程式碼生成器 + 可深度定製模板Laravel
- java模板設計模式Java設計模式
- WEB程式設計開發常用的程式碼Web程式設計
- Java Web(四) 一次性驗證碼的程式碼實現JavaWeb
- [Hook] 跨程式 Binder設計與實現 - 設計篇Hook
- 20行程式碼實現JavaScript模板引擎行程JavaScript
- Java設計模式——模板設計模式Java設計模式
- Java中的多級快取設計與實現Java快取
- Go Web 程式設計--超詳細的模板庫應用指南GoWeb程式設計
- 好程式設計師web前端教程分享js模板模式程式設計師Web前端JS模式
- 前端模板的原理與實現前端
- 程式設計實踐考試的入門模板程式設計
- 深入實踐c++模板程式設計C++程式設計
- iOS 面向切面程式設計的實現與實戰案例iOS程式設計
- 精確統計程式碼量(Java實現)Java
- 尋找Java程式碼生成器Java
- 低程式碼平臺前端的設計與實現(四)元件大綱樹的構建設計前端元件
- Titan 的設計與實現
- LFU 的設計與實現
- API的設計與實現API