https://www.cnblogs.com/jarman/p/5180270.html
在web開發過程中,尤其是後臺管理系統的開發中,少不了增刪改成的基礎操作,原來我自己的做法是一份一份的拷貝粘貼,然後修改其中的不同,然而這樣既枯燥無味又浪費了大量的時間,所以根據自己項目結構的特點寫了一個自動生成結構代碼的工具jar包,可以根據數據庫表直接生成相應數據庫模型對象(DMO)以及對錶的增刪改查代碼。
之前我考慮過多種自動生成代碼的提供方式,比如web的方式,通過在頁面文本框裏面輸入各種參數,比如模板文件地址,生成文件地址,數據庫名,數據庫用戶名和密碼等,點擊生成按鈕就可以生成源代碼文件。但這樣需要部署啓動這個web程序。使用java的圖形用戶界面,但我對java圖形的相關API並不瞭解,最後決定使用一個jar包的方式,方便簡潔。
由於模板文件使用的是freemarker,數據庫使用的是mysql,所以引入其他的兩個jar文件。
如上圖,AutoGenerationJavaCode.jar 是將原本工程裏的 AutoGenerationJavaCode.java文件打包生成的,也是最終的形式。通過在AutoGenerationDemo類main函數中設置參數,直接調用即可自動生成代碼。
配置好參數後在左圖右鍵運行java程序即可生成右圖代碼文件:
調用如下:
1 public class AutoGenerationDemo { 2 3 public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException, TemplateException { 4 //數據庫地址 5 String url = "jdbc:mysql://10.27.209.137:3306/sample"; 6 //用戶名 7 String name = "root"; 8 //密碼 9 String passWord = "root"; 10 //驅動 11 String driver = "com.mysql.jdbc.Driver"; 12 //表名 13 String tableName = "t_operate_log"; 14 //模板路徑 15 String templateDir = "F:\\template"; 16 //生成文件路徑 17 String autoGeneratedFile = "F:\\autoGenerated"; 18 //實例化 19 AutoGenerationJavaCode autoGenerationJavaCode = new AutoGenerationJavaCode(url, name, passWord, driver, 20 tableName,autoGeneratedFile,templateDir); 21 22 //調用生成java代碼方法 23 autoGenerationJavaCode.autoGenerationJavaCode(); 24 } 25 26 }
在main方法中配置好所需參數,由於代碼包含註釋,不在贅述,調用jar包中 AutoGenerationJavaCode的autoGenerationJavaCode方法即可生成,控制檯會打印文件生產完成
我的Web項目的結構採用的是三層結構,Controller層調用service層,從service層調用dao層(數據操作層),所以決定自己生成service層,dao層代碼。其實質就是將模板文件中的變量進行替換。模板文件及對應生成的java代碼如下:
jar包的源代碼如下:
package com.sun.autoGenerated; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; public class AutoGenerationJavaCode { private String url; private String name; private String passWord; private String driver; private String sql; private String tableName; private String templateDir; private String autoGeneratedFile; private static String[][] fileNameArray = new String[5][2]; static { fileNameArray[0][0] = "dmoTemplate.ftl"; fileNameArray[0][1] = "DMO.java"; fileNameArray[1][0] = "serviceTemplate.ftl"; fileNameArray[1][1] = "Service.java"; fileNameArray[2][0] = "serviceImplTemplate.ftl"; fileNameArray[2][1] = "ServiceImpl.java"; fileNameArray[3][0] = "daoTemplate.ftl"; fileNameArray[3][1] = "Dao.java"; fileNameArray[4][0] = "daoImplTemplate.ftl"; fileNameArray[4][1] = "DaoImpl.java"; } public AutoGenerationJavaCode(String url, String name, String passWord, String driver, String tableName, String autoGeneratedFile,String templateDir) { this.url = url; this.name = name; this.passWord = passWord; this.driver = driver; this.sql = "select * from " + tableName; this.tableName = tableName; this.templateDir = templateDir; this.autoGeneratedFile = autoGeneratedFile; } public void autoGenerationJavaCode() throws IOException, TemplateException, ClassNotFoundException, SQLException { Configuration cfg = new Configuration(); cfg.setDefaultEncoding("utf-8"); String className = dealTableName(); String fileName = dealClassName(className); Map<String, Object> columnMap = getColumn(); //設置模板文件路徑 cfg.setDirectoryForTemplateLoading(new File(templateDir)); Map<String, Object> rootMap = new HashMap<String, Object>(); rootMap.put("className", className); rootMap.put("columnMap", columnMap); File dir = new File(autoGeneratedFile + "\\"); //檢查目錄是否存在,不存在則創建 if (!dir.exists()) { dir.mkdir(); } for (int i = 0; i < fileNameArray.length; i++) { Template temp = cfg.getTemplate(fileNameArray[i][0]); File docFile = new File(autoGeneratedFile + "\\" + fileName + fileNameArray[i][1]); Writer docout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile))); //輸出文件 temp.process(rootMap, docout); } System.out.println("==============文件生產成功==============="); } //獲取數據庫表字段名放入map中 public Map<String, Object> getColumn() throws ClassNotFoundException, SQLException { Connection conn; PreparedStatement pStemt = null; Class.forName(driver); conn = DriverManager.getConnection(url, name, passWord); pStemt = conn.prepareStatement(sql); ResultSetMetaData rsmd = pStemt.getMetaData(); Map<String, Object> columnMap = new HashMap<String, Object>(); int size = rsmd.getColumnCount(); for (int i = 0; i < size; i++) { String columnName = dealColumnName(rsmd, i); columnMap.put(columnName, columnName); } conn.close(); return columnMap; } //將表名轉換爲DMO的字段名,比如 operate_type 轉換後爲 operateType private String dealColumnName(ResultSetMetaData rsmd, int i) throws SQLException { String columnName = rsmd.getColumnName(i + 1).toLowerCase(); String charAfterLine = String.valueOf(columnName.charAt((columnName.indexOf("_") + 1))); String convertedChar = charAfterLine.toUpperCase(); columnName = columnName.replace("_" + charAfterLine, convertedChar); return columnName; } //將表名轉換爲類型類名 比如 t_operate_log 轉換後爲 operateLog ,類名首字母應爲大寫,這裏在freemarker的模板裏直接轉換 private String dealTableName() { String className = tableName.toLowerCase().substring(tableName.indexOf("_") + 1); String charAfterLine = String.valueOf(className.charAt((className.indexOf("_") + 1))); String convertedChar = charAfterLine.toUpperCase(); className = className.replace("_" + charAfterLine, convertedChar); return className; } //將類名轉換爲文件名,java公共類名與其文件名應該相同,這裏將首字母轉換爲大寫 如operateLog 轉換後爲 OperateLog private String dealClassName(String className) { String first = className.substring(0, 1).toUpperCase(); String rest = className.substring(1, className.length()); String fileName = new StringBuffer(first).append(rest).toString(); return fileName; } }
源碼下載:http://files.cnblogs.com/files/jarman/sourceCode.zip