前段时间涉及到一个数据迁移的工作,很简单,就是迁移一部分数据到新的数据库。为了防止人工拼接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();
}
}
}
分享到:
相关推荐
本篇文章将深入探讨如何利用`DatabaseMetaData`生成数据库的DLL(在关系型数据库中,DLL通常指的是数据定义语言,如SQL的CREATE TABLE等语句),以及这个过程中的关键知识点。 1. **什么是DatabaseMetaData?** `...
例如,使用`DatabaseMetaData`接口的`getTables()`方法,可以列出所有表的信息。记得处理可能的异常,如`SQLException`。 4. **遍历表数据**: 对每个表,程序需要执行`SELECT * FROM 表名`这样的查询来获取所有...
总结来说,使用Java连接Oracle数据库并生成控制文件、SELECT SQL和建表DDL语句涉及的主要知识点有: 1. JDBC API的使用,包括连接数据库、执行SQL语句。 2. Oracle的DBMS_METADATA和DBMS_DATA_PUMP包,用于获取DDL和...
使用`Connection`对象的方法`getMetaData()`获取`DatabaseMetaData`对象,它是用于访问数据库元数据的对象。 ```java DatabaseMetaData dbmd = connection.getMetaData(); ``` 3. **获取表列表** 使用`...
在实际应用中,数据库元数据常用于生成动态SQL、数据库迁移工具、数据分析以及数据库版本控制。了解如何获取和使用这些元数据是Java开发者必备的技能之一,特别是在处理跨数据库平台的项目时。通过本实例56,你可以...
7. 使用DatabaseMetaData对象可以获取数据库的元数据,例如表名、列名等。 8. 使用ResultSet对象可以获取查询结果,例如执行SHOW CREATE TABLE语句可以获取表结构。 9. 使用Statement对象可以执行SQL语句,例如...
通过学习,参与者将能够掌握多种数据迁移技巧,包括创建和使用目录对象、使用SQL*Loader从非Oracle数据库加载数据、理解DataPump的一般架构、使用DataPump Export和Import在Oracle数据库间移动数据,以及利用外部表...
在Java编程中,我们可以使用JDBC(Java Database Connectivity)的`DatabaseMetaData`接口来获取数据库的元数据。这个接口提供了多种方法来获取关于数据库的各种信息。例如,在给出的代码示例中,`JDBCDataMeta`类...
首先,"导入系统缺少的包"可能指的是在执行数据泵导入(如`expdp`和`impdp`)或使用SQL*Loader等工具进行数据迁移时,发现某些数据库对象的依赖包没有被正确地导入或安装。为了解决这个问题,你需要先确定缺少哪些包...
- 这一步会生成三个文件:`.SQL`、`.DAT`和`.CTL`。 **步骤2:执行SQL语句创建表** 文档提供了两种方式来执行SQL语句创建表: - **方法一**:通过命令提示符窗口连接到Oracle数据库,然后打开并执行`.SQL`文件中...
手册集包含《神通数据库安装手册》《神通数据库备份恢复工具使用手册》《...迁移工具使用手册》《神通数据库审计管理指南》《神通数据库ODBC程序员开发指南》《神通数据库SQL语言参考手册》《神通数据库审计工具使用...
可以使用`DatabaseMetaData`对象,它是`Connection`的一个属性,提供了关于数据库的各种元数据信息,包括表的名称、列的名称等。例如: ```java DatabaseMetaData metaData = connection.getMetaData(); ResultSet ...
通过`DatabaseMetaData`接口,工具类可以获取数据库的元数据信息,如表名、列名、索引等,用于生成动态SQL或者数据库迁移。 8. **结果集处理**: 结果集的遍历和转换也是常见的功能,工具类可能会提供将ResultSet...
这些信息可以通过JDBC的DatabaseMetaData接口获取。有了元数据,工具就能自动生成对应的Java实体类或者映射文件,方便进行对象与关系数据库间的转换。 在数据库管理方面,"DataBase-gen"可能提供了创建、修改、删除...
至于工具,JDBC2也鼓励使用**数据库元数据(Database Metadata)**。数据库元数据API允许开发者获取关于数据库的信息,如表格、列、索引等,这在数据库脚本生成、数据库迁移或报表生成等场景中非常实用。 总结来说...
- **将一台机器上的数据库复制到另外一台机器**:使用DB2的备份和恢复功能完成数据库迁移。 - **在WIN2000下编译本地SP设置**:在Windows 2000环境下设置本地存储过程的编译选项。 - **安装另一个INSTANCE要注意的...
- **使用EXP和IMP**:`EXP`用于将数据导出到文件,`IMP`则用于将数据从文件导入到数据库,便于数据迁移和备份恢复。 通过以上知识点的详细讲解,我们可以看到Oracle数据库设计与管理是一个复杂而精细的过程,涉及到...
- **编译步骤**:使用 CMake 生成项目文件,然后使用 make 工具进行编译。 - **安装**:编译完成后,使用 make install 命令将库文件安装到系统中。 以上总结涵盖了从安装到使用的各个方面,帮助开发者全面了解如何...