1. 程式人生 > >java生成mysql資料庫建表語句、欄位、欄位型別、欄位註釋,可實現不用mysqldump備份資料庫

java生成mysql資料庫建表語句、欄位、欄位型別、欄位註釋,可實現不用mysqldump備份資料庫

使用 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  的檔案,內容如下: