java生成mysql資料庫建表語句、欄位、欄位型別、欄位註釋,可實現不用mysqldump備份資料庫
阿新 • • 發佈:2018-11-28
使用 mysqldump 備份資料庫也是可行的,因為每次備份的時候都需要mysqldump這個檔案, 我在windows備份時沒問題,但是放到linux上面時,centos系統死活不認這個檔案,但又不想裝mysql,一氣之下自己研究了個不需要mysqldump就可以備份的程式,
如果看了以下程式碼還有不懂的地方,這個網站有我的聯絡方式http://www.huashuku.top/about.htm, 站長就是我本人
廢話不多說,直接上程式碼
新增jdbc驅動 和httpClient的 maven依賴
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient-cache</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.15</version> <scope>runtime</scope> </dependency>
備份程式
package com.mysql.bak; import java.math.BigDecimal; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import com.utils.FileUtils; /** * 利用jdbc備份mysql資料庫--不用mysqldump * */ public class BakDateBase { private String DRIVER = "com.mysql.jdbc.Driver"; private String URL = null; // "jdbc:mysql://182.xxx.xxx.xxx:3306/xd_love_dev?useUnicode=true&characterEncoding=utf8"; private String USERNAME = null;// "root"; private String PASSWORD = null;//"woaini"; // 備份的檔案地址 private String filePath; private Connection conn = null; private String SQL = "SELECT * FROM ";// 資料庫操作 /** * * <建構函式> * * @param ip * 資料庫ip地址 * @param database * 資料庫名稱 * @param userName * 資料庫使用者名稱 * @param password * 密碼 * @param bakFilePath * 備份的地址 */ public BakDateBase(String ip, String database, String userName, String password, String bakFilePath) { try { Class.forName(this.DRIVER); this.URL = String.format("jdbc:mysql://%s:3306/%s?useUnicode=true&characterEncoding=utf8", ip, database); this.USERNAME = userName; this.PASSWORD = password; SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-ddHH時mm分ss秒"); String datetime = tempDate.format(new java.util.Date()); //自動加上時間戳 datetime = datetime + "_資料庫名稱:" + database ; if(bakFilePath.indexOf(".") != -1) { bakFilePath = bakFilePath.replace(".", datetime+"."); } else { bakFilePath = datetime + ".sql"; } this.filePath = bakFilePath; } catch (ClassNotFoundException e) { e.printStackTrace(); System.err.println("can not load jdbc driver"); } } /** * 獲取資料庫連線 * * @return */ private Connection getConnection() { try { if (null == conn) { conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); } } catch (SQLException e) { e.printStackTrace(); System.err.println("get connection failure"); } return conn; } /** * 關閉資料庫連線 * * @param conn */ private void closeConnection(Connection conn) { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); System.err.println("close connection failure"); } } } /** * 獲取資料庫下的所有表名 */ private List<String> getTableNames() { List<String> tableNames = new ArrayList<String>(); Connection conn = getConnection(); ResultSet rs = null; try { // 獲取資料庫的元資料 DatabaseMetaData db = conn.getMetaData(); // 從元資料中獲取到所有的表名 rs = db.getTables(null, null, null, new String[] { "TABLE" }); while (rs.next()) { tableNames.add(rs.getString(3)); } } catch (SQLException e) { e.printStackTrace(); System.err.println("getTableNames failure"); } finally { try { if (null != rs) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); System.err.println("close ResultSet failure"); } } return tableNames; } /** * 獲取表中所有欄位名稱 * * @param tableName * 表名 * @return */ private List<String> getColumnNames(String tableName) { List<String> columnNames = new ArrayList<String>(); // 與資料庫的連線 Connection conn = getConnection(); PreparedStatement pStemt = null; String tableSql = SQL + tableName; try { pStemt = conn.prepareStatement(tableSql); // 結果集元資料 ResultSetMetaData rsmd = pStemt.getMetaData(); // 表列數 int size = rsmd.getColumnCount(); for (int i = 0; i < size; i++) { columnNames.add(rsmd.getColumnName(i + 1)); } } catch (SQLException e) { System.err.println("getColumnNames failure"); e.printStackTrace(); } finally { if (pStemt != null) { try { pStemt.close(); } catch (SQLException e) { e.printStackTrace(); System.err.println("getColumnNames close pstem and connection failure"); } } } return columnNames; } /** * 獲取表中所有欄位型別 * * @param tableName * @return */ private List<String> getColumnTypes(String tableName) { List<String> columnTypes = new ArrayList<String>(); // 與資料庫的連線 Connection conn = getConnection(); PreparedStatement pStemt = null; String tableSql = SQL + tableName; try { pStemt = conn.prepareStatement(tableSql); // 結果集元資料 ResultSetMetaData rsmd = pStemt.getMetaData(); // 表列數 int size = rsmd.getColumnCount(); for (int i = 0; i < size; i++) { columnTypes.add(rsmd.getColumnTypeName(i + 1)); } } catch (SQLException e) { e.printStackTrace(); System.err.println("getColumnTypes failure"); } finally { if (pStemt != null) { try { pStemt.close(); } catch (SQLException e) { e.printStackTrace(); System.err.println("getColumnTypes close pstem and connection failure"); } } } return columnTypes; } /** * * <p> * 生成建表語句 * </p> * * @param tableName * @return * @author 葉新東(18126064335) 2018年9月6日 上午9:35:49 */ private String generateCreateTableSql(String tableName) { String sql = String.format("SHOW CREATE TABLE %s", tableName); Connection conn = null; PreparedStatement pstmt = null; try { conn = getConnection(); pstmt = (PreparedStatement) conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { // 返回建表語句語句,查詢結果的第二列是建表語句,第一列是表名 return rs.getString(2); } } catch (Exception e) { e.printStackTrace(); try { if (null != pstmt) { pstmt.close(); } } catch (Exception e2) { e.printStackTrace(); System.err.println("關閉流異常"); } } return null; } /** * 獲取表中欄位的所有註釋 * * @param tableName * @return */ private List<String> getColumnComments(String tableName) { // 與資料庫的連線 Connection conn = getConnection(); PreparedStatement pStemt = null; String tableSql = SQL + tableName; List<String> columnComments = new ArrayList<String>();// 列名註釋集合 ResultSet rs = null; try { pStemt = conn.prepareStatement(tableSql); rs = pStemt.executeQuery("show full columns from " + tableName); while (rs.next()) { columnComments.add(rs.getString("Comment")); } } catch (SQLException e) { e.printStackTrace(); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); System.err.println("getColumnComments close ResultSet and connection failure"); } } } return columnComments; } /** * * <p> * 備份表資料 * </p> * * @param tableName * @return * @author () 2018年9月6日 上午10:18:07 */ private String bakTableData(String tableName) { Connection conn = null; PreparedStatement pstmt = null; try { // 備份建表語句 String createTableSql = generateCreateTableSql(tableName); createTableSql = String.format( "\n\n\n/**\n * table name :<%s>\n *\n */\n%s\n", tableName, createTableSql); FileUtils.writeFileContent(filePath, createTableSql); // 獲取欄位型別 List<String> columnTypes = getColumnTypes(tableName); // 獲取所有 欄位 List<String> columnNames = getColumnNames(tableName); String columnArrayStr = null; for (String column : columnNames) { if (null == columnArrayStr) { columnArrayStr = "`" + column + "`"; } else { columnArrayStr = columnArrayStr + "," + "`" + column + "`"; } } String sql = String.format("select %s from %s", columnArrayStr, tableName); conn = getConnection(); pstmt = (PreparedStatement) conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { String rowValues = getRowValues(rs, columnNames.size(), columnTypes); // 返回建表語句語句,查詢結果的第二列是建表語句,第一列是表名 String insertSql = String.format("insert into %s (%s) values(%s);", tableName, columnArrayStr, rowValues); System.out.println(insertSql); insertSql = insertSql.replaceAll("\n", "<br/>"); insertSql = insertSql + "\n"; FileUtils.writeFileContent(filePath, insertSql); } } catch (Exception e) { e.printStackTrace(); try { if (null != pstmt) { pstmt.close(); } } catch (Exception e2) { e.printStackTrace(); System.err.println("關閉流異常"); } } return null; } /** * * <p> * 獲取表資料一行的所有值 * </p> * * @param rs * @param size * @author 2018年9月6日 上午11:03:05 */ private String getRowValues(ResultSet rs, int size, List<String> columnTypeList) { try { String rowValues = null; for (int i = 1; i <= size; i++) { String columnValue = null; // 獲取欄位值 columnValue = getValue(rs, i, columnTypeList.get(i - 1)); // 如果是空值不新增單引號 if (null != columnValue) { columnValue = "'" + columnValue + "'"; } // 拼接欄位值 if (null == rowValues) { rowValues = columnValue; } else { rowValues = rowValues + "," + columnValue; } } return rowValues; } catch (Exception e) { e.printStackTrace(); System.out.println("獲取表資料一行的所有值異常"); return null; } } /** * * <p> * 根據型別獲取欄位值 * </p> * * @param obj * @return * @author 2018年9月6日 上午11:16:00 */ private String getValue(ResultSet resultSet, Integer index, String columnType) { try { if ("int".equals(columnType) || "INT".equals(columnType)) { // 整數 Object intValue = resultSet.getObject(index); if (null == intValue) { return null; } return intValue + ""; } else if ("bigint".equals(columnType) || "BIGINT".equals(columnType)) { // 長整形 Object value = resultSet.getObject(index); if (null == value) { return null; } return value + ""; } else if ("smallint".equals(columnType) || "SMALLINT".equals(columnType)) { // 整數 Object value = resultSet.getObject(index); if (null == value) { return null; } return value + ""; } else if ("tinyint".equals(columnType) || "TINYINT".equals(columnType)) { // 整數 Object value = resultSet.getObject(index); if (null == value) { return null; } return value + ""; } else if ("mediumint".equals(columnType) || "MEDIUMINT".equals(columnType)) { // 長整形 Object value = resultSet.getObject(index); if (null == value) { return null; } return value + ""; } else if ("integer".equals(columnType) || "INTEGER".equals(columnType)) { // 整數 Object value = resultSet.getObject(index); if (null == value) { return null; } return value + ""; } else if ("float".equals(columnType) || "FLOAT".equals(columnType)) { // 浮點數 Object value = resultSet.getObject(index); if (null == value) { return null; } return value + ""; } else if ("double".equals(columnType) || "DOUBLE".equals(columnType)) { // 浮點數 Object value = resultSet.getObject(index); if (null == value) { return null; } return value + ""; } else if ("decimal".equals(columnType) || "DECIMAL".equals(columnType)) { // 浮點數-金額型別 BigDecimal value = resultSet.getBigDecimal(index); if (null == value) { return null; } return value.toString(); } else if ("char".equals(columnType) || "CHAR".equals(columnType)) { // 字串型別 String value = resultSet.getString(index); return value; } else if ("varchar".equals(columnType) || "VARCHAR".equals(columnType)) { // 字串型別 String value = resultSet.getString(index); return value; } else if ("tinytext".equals(columnType) || "TINYTEXT".equals(columnType)) { // 字串型別 String value = resultSet.getString(index); return value; } else if ("text".equals(columnType) || "TEXT".equals(columnType)) { // 字串型別 String value = resultSet.getString(index); return value; } else if ("mediumtext".equals(columnType) || "MEDIUMTEXT".equals(columnType)) { // 字串型別 String value = resultSet.getString(index); return value; } else if ("longtext".equals(columnType) || "LONGTEXT".equals(columnType)) { // 字串型別 String value = resultSet.getString(index); return value; } else if ("year".equals(columnType) || "YEAR".equals(columnType)) { // 時間型別:範圍 1901/2155 格式 YYYY String year = resultSet.getString(index); if (null == year) { return null; } // 只需要年的字元即可, return year.substring(0, 4); } else if ("date".equals(columnType) || "DATE".equals(columnType)) { // 時間型別:範圍 '1000-01-01'--'9999-12-31' 格式 YYYY-MM-DD return resultSet.getString(index); } else if ("time".equals(columnType) || "TIME".equals(columnType)) { // 時間型別:範圍 '-838:59:59'到'838:59:59' 格式 HH:MM:SS return resultSet.getString(index); } else if ("datetime".equals(columnType) || "DATETIME".equals(columnType)) { // 時間型別:範圍 '1000-01-01 00:00:00'--'9999-12-31 23:59:59' 格式 YYYY-MM-DD HH:MM:SS return resultSet.getString(index); } else if ("timestamp".equals(columnType) || "TIMESTAMP".equals(columnType)) { // 時間型別:範圍 1970-01-01 00:00:00/2037 年某時 格式 YYYYMMDD HHMMSS 混合日期和時間值,時間戳 return resultSet.getString(index); } else { return null; } } catch (Exception e) { e.printStackTrace(); System.err.println("獲取資料庫型別值異常"); return null; } } /** * * <開始備份> * * @author 2018年9月6日 下午3:30:43 */ public void startBak() { try { List<String> tableNames = getTableNames(); System.out.println("tableNames:" + tableNames); for (String tableName : tableNames) { bakTableData(tableName); // System.out.println(generateCreateTableSql(tableName)); // System.out.println("ColumnNames:" + getColumnNames(tableName)); // System.out.println("ColumnTypes:" + getColumnTypes(tableName)); // System.out.println("ColumnComments:" + getColumnComments(tableName)); } // 統一關閉連線 closeConnection(conn); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new BakDateBase("182.xxx.xxx.xxx", "xd_love_dev", "root", "woaini", "f:\\bak.sql").startBak(); } }
執行 main 方法後會在磁碟指定位置生成 .sql 的檔案,內容如下: