`
iMzw
  • 浏览: 193960 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

数据迁移(使用DatabaseMetaData生成SQL)

    博客分类:
  • Java
阅读更多
前段时间涉及到一个数据迁移的工作,很简单,就是迁移一部分数据到新的数据库。为了防止人工拼接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(" (");
		DatabaseMetaData metadata = rs.getStatement().getConnection().getMetaData();
		insertSQLBuilder.append(getColumnsString(metadata, tableName));
		insertSQLBuilder.append(") values (");

		String[] cols = getColumnsArray(metadata, tableName);
		int len = cols.length;
		for (int i = 0; i < len; i++) {
			String value = StringUtils.trimToEmpty(rs.getString(cols[i]));
			if (i != len - 1) {
				insertSQLBuilder.append("'").append(value).append("', ");
			} else {
				insertSQLBuilder.append("'").append(value).append("' ");
			}
		}
		insertSQLBuilder.append(")");

		return insertSQLBuilder.toString();
	}

	/**
	 * 根据表名数据库元数据和条件生成查询语句
	 * 
	 * @param metadata
	 * @param tableName
	 * @param condition
	 *            查询条件 (eg:where ID=1)
	 * @return
	 * @throws SQLException
	 */
	private static String generateQuerySQL(DatabaseMetaData metadata, String tableName, String condition) throws SQLException {
		StringBuilder queryBuilder = new StringBuilder();
		queryBuilder.append("select ");

		queryBuilder.append(getColumnsString(metadata, tableName));

		queryBuilder.append(" from ").append(tableName).append(" ").append(condition);

		return queryBuilder.toString();
	}

	private static String getColumnsString(DatabaseMetaData metadata, String tableName) throws SQLException {
		String[] cols = getColumnsArray(metadata, tableName);
		return StringUtils.join(cols, ", ");
	}

	/**
	 * 根据表名和数据库元数据获得所有列的List
	 * 
	 * @param metadata
	 * @param tableName
	 * @return
	 * @throws SQLException
	 */
	private static List<String> getColumnsList(DatabaseMetaData metadata, String tableName) throws SQLException {
		List<String> columns = new ArrayList<String>();

		ResultSet rs = metadata.getColumns(null, null, tableName, "%");
		while (rs.next()) {
			columns.add(rs.getString("COLUMN_NAME"));
		}

		return columns;
	}

	/**
	 * 根据表名和数据库元数据获得所有列的数组。
	 * 
	 * @param metadata
	 * @param tableName
	 * @return
	 * @throws SQLException
	 */
	private static String[] getColumnsArray(DatabaseMetaData metadata, String tableName) throws SQLException {
		List<String> list = getColumnsList(metadata, tableName);
		return list.toArray(new String[list.size()]);
	}

	private static void loadDirver() {
		try {
			Class.forName("com.ibm.db2.jcc.DB2Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

0
0
分享到:
评论

相关推荐

    DatabaseMetaData生成数据库DLL

    本篇文章将深入探讨如何利用`DatabaseMetaData`生成数据库的DLL(在关系型数据库中,DLL通常指的是数据定义语言,如SQL的CREATE TABLE等语句),以及这个过程中的关键知识点。 1. **什么是DatabaseMetaData?** `...

    java程序读取数据库表 转为sql文件 仅供参考 不得宣传

    例如,使用`DatabaseMetaData`接口的`getTables()`方法,可以列出所有表的信息。记得处理可能的异常,如`SQLException`。 4. **遍历表数据**: 对每个表,程序需要执行`SELECT * FROM 表名`这样的查询来获取所有...

    使用java连接数据库按需生成oracle卸数装数的control、selectSQL、建表ddl语句等文件

    总结来说,使用Java连接Oracle数据库并生成控制文件、SELECT SQL和建表DDL语句涉及的主要知识点有: 1. JDBC API的使用,包括连接数据库、执行SQL语句。 2. Oracle的DBMS_METADATA和DBMS_DATA_PUMP包,用于获取DDL和...

    java获取数据库主外键

    使用`Connection`对象的方法`getMetaData()`获取`DatabaseMetaData`对象,它是用于访问数据库元数据的对象。 ```java DatabaseMetaData dbmd = connection.getMetaData(); ``` 3. **获取表列表** 使用`...

    JAVA100例之实例56 数据库元数据

    在实际应用中,数据库元数据常用于生成动态SQL、数据库迁移工具、数据分析以及数据库版本控制。了解如何获取和使用这些元数据是Java开发者必备的技能之一,特别是在处理跨数据库平台的项目时。通过本实例56,你可以...

    jsp数据库脱裤脚本,脱各种数据库

    7. 使用DatabaseMetaData对象可以获取数据库的元数据,例如表名、列名等。 8. 使用ResultSet对象可以获取查询结果,例如执行SHOW CREATE TABLE语句可以获取表结构。 9. 使用Statement对象可以执行SQL语句,例如...

    Less18_MovingData_MB3.pdf

    通过学习,参与者将能够掌握多种数据迁移技巧,包括创建和使用目录对象、使用SQL*Loader从非Oracle数据库加载数据、理解DataPump的一般架构、使用DataPump Export和Import在Oracle数据库间移动数据,以及利用外部表...

    数据库元数据资料,关于oracle的

    在Java编程中,我们可以使用JDBC(Java Database Connectivity)的`DatabaseMetaData`接口来获取数据库的元数据。这个接口提供了多种方法来获取关于数据库的各种信息。例如,在给出的代码示例中,`JDBCDataMeta`类...

    OracleXE 导入系统缺少的包 更改字符集sql命令

    首先,"导入系统缺少的包"可能指的是在执行数据泵导入(如`expdp`和`impdp`)或使用SQL*Loader等工具进行数据迁移时,发现某些数据库对象的依赖包没有被正确地导入或安装。为了解决这个问题,你需要先确定缺少哪些包...

    Oracle数据库完全入库过程介绍.docx

    - 这一步会生成三个文件:`.SQL`、`.DAT`和`.CTL`。 **步骤2:执行SQL语句创建表** 文档提供了两种方式来执行SQL语句创建表: - **方法一**:通过命令提示符窗口连接到Oracle数据库,然后打开并执行`.SQL`文件中...

    神通数据库文档.pdf

    手册集包含《神通数据库安装手册》《神通数据库备份恢复工具使用手册》《...迁移工具使用手册》《神通数据库审计管理指南》《神通数据库ODBC程序员开发指南》《神通数据库SQL语言参考手册》《神通数据库审计工具使用...

    导出数据库表结成words 代码

    可以使用`DatabaseMetaData`对象,它是`Connection`的一个属性,提供了关于数据库的各种元数据信息,包括表的名称、列的名称等。例如: ```java DatabaseMetaData metaData = connection.getMetaData(); ResultSet ...

    JAVA操作mysql工具类

    通过`DatabaseMetaData`接口,工具类可以获取数据库的元数据信息,如表名、列名、索引等,用于生成动态SQL或者数据库迁移。 8. **结果集处理**: 结果集的遍历和转换也是常见的功能,工具类可能会提供将ResultSet...

    DataBase-gen:第一次提交

    这些信息可以通过JDBC的DatabaseMetaData接口获取。有了元数据,工具就能自动生成对应的Java实体类或者映射文件,方便进行对象与关系数据库间的转换。 在数据库管理方面,"DataBase-gen"可能提供了创建、修改、删除...

    JDBC2

    至于工具,JDBC2也鼓励使用**数据库元数据(Database Metadata)**。数据库元数据API允许开发者获取关于数据库的信息,如表格、列、索引等,这在数据库脚本生成、数据库迁移或报表生成等场景中非常实用。 总结来说...

    牛新庄:DB2使用经验

    - **将一台机器上的数据库复制到另外一台机器**:使用DB2的备份和恢复功能完成数据库迁移。 - **在WIN2000下编译本地SP设置**:在Windows 2000环境下设置本地存储过程的编译选项。 - **安装另一个INSTANCE要注意的...

    oracle数据库设计

    - **使用EXP和IMP**:`EXP`用于将数据导出到文件,`IMP`则用于将数据从文件导入到数据库,便于数据迁移和备份恢复。 通过以上知识点的详细讲解,我们可以看到Oracle数据库设计与管理是一个复杂而精细的过程,涉及到...

    c++ 连接 mysql 官方文档

    - **编译步骤**:使用 CMake 生成项目文件,然后使用 make 工具进行编译。 - **安装**:编译完成后,使用 make install 命令将库文件安装到系统中。 以上总结涵盖了从安装到使用的各个方面,帮助开发者全面了解如何...

Global site tag (gtag.js) - Google Analytics