備忘,很多代碼是從別人的博客里找的,有做一些修改。
基本情況是,比如現在我有一個現成的數據庫,里面有百十個表,每個表有10幾20個字段。
在java代碼里使用需要每個表對應一個實體,如何獲取這些實體類呢?最直接的方式,一個個表,一個個字段手工coding。這種方式有一個不好的地方:如果表和字段很多,怕是實體沒寫完,人進醫院了。
所以想,寫一個小小的程序,提供數據庫連接的必要信息,用生成這些實體類,使用的時候就放到main方法里運行就行。

public class EntitiesGenerator { // 數據庫連接 private String URL; private String DBName; private String NAME; private String PASS; private String authorName = "eric";// 作者名字 private String[] colnames; // 列名數組 private String[] colTypes; // 列名類型數組 private int[] colSizes; // 列名大小數組 private boolean f_util = false; // 是否需要導入包java.util.* private boolean f_sql = false; // 是否需要導入包java.sql.* private SqlHelper sqlHelper = null; /* * 構造函數 */ public EntitiesGenerator(String url, String dbname, String username, String password) { this.URL = url + "/" + dbname; this.DBName = dbname; this.NAME = username; this.PASS = password; sqlHelper = new SqlHelper(this.URL, this.NAME, this.PASS); } public void Generate() { List<String> tableNames = sqlHelper.Get( "SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='" + DBName + "';", "TABLE_NAME"); Connection con = null; try { con = sqlHelper.getConnection(); } catch (ClassNotFoundException | SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } for (String table : tableNames) { Generate(table, con); System.out.println("generated: "+table ); resetTableInfo(); } try { sqlHelper.closeConnection(con); } catch (ClassNotFoundException | SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void resetTableInfo(){ colnames = null; colTypes=null; colSizes=null; f_util=false; f_sql=false; } private String getPackageOutPath() { return "com.eric.learning.entity." + DBName; } private void Generate(String tablename, Connection con) { if (con == null) { System.out.println("------------------Connection to database was not set up------------------"); return; } // 查要生成實體類的表 String sql = "SELECT * FROM " + tablename + " limit 0, 1;"; PreparedStatement pStemt = null; try { pStemt = con.prepareStatement(sql); ResultSetMetaData rsmd = pStemt.getMetaData(); int size = rsmd.getColumnCount(); // 統計列 colnames = new String[size]; colTypes = new String[size]; colSizes = new int[size]; for (int i = 0; i < size; i++) { colnames[i] = rsmd.getColumnName(i + 1).replace(" ", ""); colTypes[i] = rsmd.getColumnTypeName(i + 1); if (colTypes[i].equalsIgnoreCase("datetime") || colTypes[i].equalsIgnoreCase("date")) { f_util = true; } if (colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text") || colTypes[i].equalsIgnoreCase("TIMESTAMP")) { f_sql = true; } colSizes[i] = rsmd.getColumnDisplaySize(i + 1); } String content = parse(colnames, colTypes, colSizes, tablename); try { File directory = new File(""); File dir = new File(directory.getAbsolutePath() + "/src/" + this.getPackageOutPath().replace(".", "/")); dir.mkdirs(); String outputPath = dir.getAbsolutePath() + "/" + initcap(tablename) + ".java"; FileWriter fw = new FileWriter(outputPath); PrintWriter pw = new PrintWriter(fw); pw.println(content); pw.flush(); pw.close(); } catch (IOException e) { e.printStackTrace(); } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (pStemt != null) { pStemt.close(); } } catch (SQLException e) { e.printStackTrace(); } } } /** * 功能:生成實體類主體代碼 * * @param colnames * @param colTypes * @param colSizes * @return */ private String parse(String[] colnames, String[] colTypes, int[] colSizes, String tablename) { StringBuffer sb = new StringBuffer(); sb.append("package " + this.getPackageOutPath() + ";\r\n"); // 判斷是否導入工具包 if (f_util) { sb.append("import java.util.Date;\r\n"); } if (f_sql) { sb.append("import java.sql.*;\r\n"); } sb.append("\r\n"); // 注釋部分 sb.append("/**\r\n"); sb.append(" * " + tablename); SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm"); sb.append(" generated at " + formater.format(new Date()) + " by: " + this.authorName + "\r\n"); sb.append(" */"); // 實體部分 sb.append("\r\n\r\npublic class " + initcap(tablename) + "{\r\n"); processAllAttrs(sb);// 屬性 processAllMethod(sb);// get set方法 sb.append("}"); return sb.toString(); } /** * 功能:生成所有屬性 * * @param sb */ private void processAllAttrs(StringBuffer sb) { for (int i = 0; i < colnames.length; i++) { sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + colnames[i] + ";\r\n"); } sb.append(System.lineSeparator()); } /** * 功能:生成所有方法 * * @param sb */ private void processAllMethod(StringBuffer sb) { for (int i = 0; i < colnames.length; i++) { sb.append("\tpublic void set" + initcap(colnames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " " + colnames[i] + "){\r\n"); sb.append("\t\tthis." + colnames[i] + "=" + colnames[i] + ";\r\n"); sb.append("\t}\r\n\r\n"); sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colnames[i]) + "(){\r\n"); sb.append("\t\treturn " + colnames[i] + ";\r\n"); sb.append("\t}\r\n\r\n"); } } /** * 功能:將輸入字符串的首字母改成大寫 * * @param str * @return */ private String initcap(String str) { char[] ch = str.toCharArray(); if (ch[0] >= 'a' && ch[0] <= 'z') { ch[0] = (char) (ch[0] - 32); } return new String(ch); } /** * 功能:獲得列的數據類型 * * @param sqlType * @return */ private String sqlType2JavaType(String sqlType) { if (sqlType.equalsIgnoreCase("bit")) { return "boolean"; } else if (sqlType.equalsIgnoreCase("tinyint") || sqlType.equalsIgnoreCase("tinyINT UNSIGNED")) { return "byte"; } else if (sqlType.equalsIgnoreCase("smallint")) { return "short"; } else if (sqlType.equalsIgnoreCase("int") || sqlType.equalsIgnoreCase("INT UNSIGNED")) { return "int"; } else if (sqlType.equalsIgnoreCase("bigint")) { return "long"; } else if (sqlType.equalsIgnoreCase("float")) { return "float"; } else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric") || sqlType.equalsIgnoreCase("real") || sqlType.equalsIgnoreCase("money") || sqlType.equalsIgnoreCase("smallmoney")||sqlType.equalsIgnoreCase("DOUBLE") ) { return "double"; } else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char") || sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nchar") || sqlType.equalsIgnoreCase("text")) { return "String"; } else if (sqlType.equalsIgnoreCase("datetime") || sqlType.equalsIgnoreCase("date")) { return "Date"; } else if (sqlType.equalsIgnoreCase("image")) { return "Blod"; }else if (sqlType.equalsIgnoreCase("TIMESTAMP")){ return "Timestamp"; } return null; } }
使用到的類SqlHelper,沒有完整的實現各種查詢方法(暫時用不到):

public class SqlHelper { private String url; private String username; private String password; private Connection connection; private static final String DRIVER = "com.mysql.jdbc.Driver"; public SqlHelper(String url, String username, String password) { this.url = url; this.username = username; this.password = password; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public List<HashMap<String, Object>> Get(String sql) { List<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>(); Statement statement = null; try { statement = getStatement(); ResultSet set = statement.executeQuery(sql); ResultSetMetaData meta = set.getMetaData(); int columnCount = meta.getColumnCount(); System.out.println(columnCount); while (set.next()) { HashMap<String, Object> row = new HashMap<>(); for (int i = 1; i <= columnCount; i++) { String column = meta.getColumnName(i); row.put(column, set.getObject(column)); } result.add(row); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { closeStatement(statement); } catch (SQLException e) { e.printStackTrace(); } } return result; } @SuppressWarnings("unchecked") public <T> List<T> Get(String sql, String columnName) { List<T> result = new ArrayList<T>(); Statement statement = null; try { statement = getStatement(); ResultSet set = statement.executeQuery(sql); while (set.next()) { result.add((T) set.getObject(columnName)); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { try { closeStatement(statement); } catch (SQLException e) { e.printStackTrace(); } } return result; } public Statement getStatement() throws ClassNotFoundException, SQLException{ Class.forName(DRIVER); Connection con = DriverManager.getConnection(url, username, password); Statement statement = con.createStatement(); return statement; } public Connection getConnection() throws ClassNotFoundException, SQLException { if (connection == null) { Class.forName(DRIVER); connection = DriverManager.getConnection(url, username, password); } return connection; } public void closeConnection(Connection conn) throws ClassNotFoundException, SQLException { if (connection != null) { connection.close(); } if (conn != null) { conn.close(); } System.out.println("-----------Connection closed now-----------"); } public void closeStatement(Statement statement) throws SQLException { if (statement != null) { Connection con = statement.getConnection(); statement.close(); if (con != null) { con.close(); } } } }
在main方法里調用:
EntitiesGenerator gen = new EntitiesGenerator("jdbc:mysql://xx.xx.xx.xx:xxxx", "xxx", "xxx", "xxx"); gen.Generate();
這里是連接mysql生成實體的,所以項目里一定需要有mysql的驅動jar包。