日期:2014-05-16  浏览次数:20464 次

数据迁移(使用DatabaseMetaData生成SQL)
前段时间涉及到一个数据迁移的工作,很简单,就是迁移一部分数据到新的数据库。为了防止人工拼接SQL时出现错位,就顺手写了一个根据数据库元数据来生成SQL语句的类。以下是一些最基本的工具方法。



import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public class DataMigrationTool {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		loadDirver();

		String[] ids = { "109159947", "173902327", "757427151", "125380114", "715426426" };

		List<String> list = exportDataSQL(ids);

		URL url = DataMigrationTool.class.getResource("");
		Date now = new Date();
		SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd_HH-mm_ss_SSS");
		String filePath = new File(url.getFile() + "exported_data_" + formater.format(now) + ".sql").getAbsolutePath();

		writeSQLFile(filePath, list);
	}

	private static List<String> exportDataSQL(String[] ids) {
		List<String> allList = new ArrayList<String>();
		for (String id : ids {
			allList.add("------------------------------------------------");
			allList.add("-- Data for id: " + id);
			allList.add("------------------------------------------------");
			List<String> list = generateSQLList(id);
			allList.addAll(list);
		}

		return allList;
	}

	public static void writeSQLFile(String filePath, List<String> stringList) {
		System.out.println("导出流程数据(SQL语句格式)到:" + filePath);
		FileWriter writer = null;
		try {
			writer = new FileWriter(new File(filePath));
			for (String sql : stringList) {
				System.out.println(sql);
				writer.write(sql + "\n");
			}
			writer.flush();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 根据id生成导出数据的SQL
	 * 
	 * @param id
	 * @return
	 */
	public static List<String> generateSQLList(String id) {
		List<String> sqlList = new ArrayList<String>();

		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			con = DriverManager.getConnection("", "", "");
			stmt = con.createStatement();

			DatabaseMetaData metadata = con.getMetaData();
			System.out.println(metadata.getDatabaseProductName() + " " + metadata.getDatabaseMajorVersion() + "."
					+ metadata.getDatabaseMinorVersion());

			String tableName = "TEST";
			// /////////////////////////////////////////////////////
			// 导出TEST
			// /////////////////////////////////////////////////////
			sqlList.add("-- "+tableName);

			String sql = generateQuerySQL(metadata, tableName, "where ID='" + id + "'");
			//System.out.println(queryWorkFlowSQL);

			rs = stmt.executeQuery(sql);
			String workflow_expand = "";
			while (rs.next()) {
				String insertSQL = generateInsertSQL(rs, tableName);
				sqlList.add(insertSQL);
				// System.out.println(insertSQL);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (stmt != null)
					stmt.close();
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return sqlList;
	}

	/**
	 * 根据结果集和表名生成INSERT语句。
	 * 
	 * @param rs
	 * @param tableName
	 * @return
	 * @throws SQLException
	 */
	private static String generateInsertSQL(ResultSet rs, String tableName) throws SQLException {
		if (rs == null)
			return "";
		StringBuilder insertSQLBuilder = new StringBuilder();
		insertSQLBuilder.append("insert into ").append(tableName).append