JDBC获得DB2表结构并且将表中数据脱敏后转移的程序示例
完整项目地址:https://github.com/zifeiy/totomi
代码示例:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.anbank.totomi.assist.TimeRecorder;
import com.anbank.totomi.config.TotomiConfigure;
import com.anbank.totomi.po.TotomiTableColumn;
public class DbTransfer {
private Connection connection1;
private Connection connection2;
private long theDataSelectedCount;
private TimeRecorder timeRecorder;
private MySQLRecorder mySQLRecorder;
private EncodingEngine encodingEngine;
public DbTransfer() {
try {
Class.forName(TotomiConfigure.DB2_CLASS_NAME);
connection1 = DriverManager.getConnection(TotomiConfigure.DB2_INST1_URL, TotomiConfigure.DB2_INST1_USERNAME, TotomiConfigure.DB2_INST1_PASSWORD);
connection2 = DriverManager.getConnection(TotomiConfigure.DB2_INST2_URL, TotomiConfigure.DB2_INST2_USERNAME, TotomiConfigure.DB2_INST2_PASSWORD);
theDataSelectedCount = 0;
timeRecorder = new TimeRecorder();
mySQLRecorder = new MySQLRecorder();
mySQLRecorder.forceClean();
encodingEngine = new EncodingEngine();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private List<String> getAllTableNames() {
try {
List<String> tableNameList = new ArrayList<String>();
DatabaseMetaData databaseMetaData1 = connection1.getMetaData();
ResultSet resultSet = databaseMetaData1.getTables(null, TotomiConfigure.DB2_INST1_SCHEMA, null, new String[] { "TABLE" });
while (resultSet.next()) {
String tableName=resultSet.getString("TABLE_NAME");
tableNameList.add(tableName);
}
return tableNameList;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public void handle() {
List<String> tableNameList = this.getAllTableNames();
for (String tableName : tableNameList) {
try {
handleOneTable(tableName);
} catch (Exception e) {
mySQLRecorder.updateFailed(tableName);
}
}
}
public void handleOneTable(String tableName) {
if (mySQLRecorder.CheckSucceedSolved(tableName)) {
return;
}
mySQLRecorder.updateProcessing(tableName);
tableName = tableName.toUpperCase();
List<TotomiTableColumn> columnList = new ArrayList<TotomiTableColumn>();
String checkString = null;
try {
DatabaseMetaData databaseMetaData1 = connection1.getMetaData();
ResultSet resultSet = databaseMetaData1.getColumns(null, TotomiConfigure.DB2_INST1_SCHEMA, tableName, "%");
// DELETE TABLE SQL
String deleteTableSQL = String.format("DROP TABLE %s.%s", TotomiConfigure.DB2_INST2_SCHEMA, tableName);
// CREATE TABLE SQL
String createTableSQL = String.format("CREATE TABLE %s.%s (", TotomiConfigure.DB2_INST2_SCHEMA, tableName);
// SELECT SQL
String selectSQL = "SELECT ";
boolean flag = false;
boolean hasClobOrBlob = false;
while (resultSet.next()) {
if (flag) {
createTableSQL += ",\n\t";
selectSQL += ",";
}
else
createTableSQL += "\n\t";
flag = true;
String columnName = resultSet.getString("COLUMN_NAME");
String typeName = resultSet.getString("TYPE_NAME");
int columnSize = resultSet.getInt("COLUMN_SIZE");
int decimalDigits = resultSet.getInt("DECIMAL_DIGITS");
columnList.add(new TotomiTableColumn(columnName, typeName, columnSize, decimalDigits));
// System.out.println(new TotomiTableColumn(columnName, typeName, columnSize, decimalDigits).toString());
selectSQL += columnName;
String oneColumnDesc = columnName + " " + typeName;
if (typeName.equals("CHARACTER") || typeName.equals("VARCHAR") || typeName.equals("CHAR") || typeName.equals("VARGRAPHIC") || typeName.equals("GRAPHIC")
|| typeName.equals("BLOB") || typeName.equals("CLOB") ) {
oneColumnDesc += "(" + columnSize + ")";
}
else if (typeName.equals("DECIMAL")) {
oneColumnDesc += "(" + columnSize + "," + decimalDigits + ")";
}
else
if (typeName.equals("DATE") || typeName.equals("TIMESTAMP") || typeName.equals("INTEGER") || typeName.equals("SMALLINT") || typeName.equals("BIGINT")) {
;
}
createTableSQL += oneColumnDesc;
// check if contains Clob or Blob
if (typeName.equals("CLOB") || typeName.equals("BLOB")) {
hasClobOrBlob = true;
}
}
createTableSQL += "\n)";
selectSQL += " FROM " + TotomiConfigure.DB2_INST1_SCHEMA + "." + tableName;
// DB2 Inst2 insert
String insertPrefix = "INSERT INTO " + TotomiConfigure.DB2_INST2_SCHEMA + "." + tableName + " (";
for (int i = 0; i < columnList.size(); i ++) {
if (i > 0) {
insertPrefix += ",";
}
TotomiTableColumn column = columnList.get(i);
insertPrefix += column.getColumnName();
}
insertPrefix += ") VALUES (";
// // test
// System.out.println("DEL SQL:\n" + deleteTableSQL);
// System.out.println("CREATE SQL:\n" + createTableSQL);
// System.out.println("SELECT SQL:\n" + selectSQL);
// System.out.println("INSERT Prefix: " + insertPrefix);
Statement statement1 = connection1.createStatement();
Statement statement2 = connection2.createStatement();
try {
statement2.execute(deleteTableSQL);
} catch (com.ibm.db2.jcc.am.SqlSyntaxErrorException e1) {
// System.out.println("删除 " + TotomiConfigure.DB2_INST2_SCHEMA + "." + tableName + " 失败,很有很能是因为没有这个表 !!");
}
statement2.execute(createTableSQL);
resultSet = statement1.executeQuery(selectSQL);
int cnt = 0;
Map<Integer, Clob> tmpClobMap = new HashMap<Integer, Clob>();
// Map<Integer, Blob> tmpBlobMap = new HashMap<Integer, Blob>();
Set<Integer> tmpBlobSet = new HashSet<Integer>();
while (resultSet.next()) {
theDataSelectedCount ++;
if (theDataSelectedCount % 10000 == 0) {
System.out.println("获取 " + theDataSelectedCount + " 条数据,历时:\t" + timeRecorder.getTime() + "\t当前表名称:" + tableName);
}
int bcIdx = 0;
tmpClobMap.clear();
// tmpBlobMap.clear();
tmpBlobSet.clear();
String insertSuffix = "";
for (int i = 0; i < columnList.size(); i ++) {
if (i > 0) {
insertSuffix += ",";
}
TotomiTableColumn column = columnList.get(i);
String typeName = column.getTypeName();
boolean needQuot = false;
if (typeName.equals("CHARACTER") || typeName.equals("VARCHAR") || typeName.equals("CHAR") || typeName.equals("DATE") || typeName.equals("TIMESTAMP")
|| typeName.equals("XML") || typeName.equals("DATE") || typeName.equals("TIME")
|| typeName.equals("VARGRAPHIC") || typeName.equals("GRAPHIC") ) {
needQuot = true;
}
String value = resultSet.getString(column.getColumnName());
if (value == null || value.toUpperCase().equals("NULL")) {
needQuot = false;
}
// CLOB type special judge
if (value != null && column.getTypeName().equals("CLOB")) {
Clob clob = resultSet.getClob(column.getColumnName());
bcIdx ++;
tmpClobMap.put(bcIdx, clob);
value = "?";
}
// BLOB type special judge
if (value != null && column.getTypeName().equals("BLOB")) {
Blob blob = resultSet.getBlob(column.getColumnName());
bcIdx ++;
// tmpBlobMap.put(bcIdx, blob);
tmpBlobSet.add(bcIdx);
value = "?";
File f = new File(String.format(TotomiConfigure.Tmp_Blob_file_Path_Format, bcIdx));
OutputStream out = null ;
out = new FileOutputStream(f) ;
out.write(blob.getBytes(1,(int)blob.length())) ;
out.close() ;
}
insertSuffix += (needQuot ? "'" : "");
if (value != null && (typeName.equals("CHARACTER") || typeName.equals("VARCHAR") || typeName.equals("CHAR"))) {
value = value.trim();
value = encodingEngine.encode(tableName, column.getColumnName(), value);
}
insertSuffix += (value == null ? null : value.replaceAll("'", "''"));
insertSuffix += (needQuot ? "'" : "");
}
insertSuffix += ")";
String insertSQL = insertPrefix + insertSuffix;
// System.out.println("insert SQL: " + insertSQL);
if (hasClobOrBlob) {
PreparedStatement preparedStatement = connection2.prepareStatement(insertSQL);
for (Entry<Integer, Clob> entry : tmpClobMap.entrySet()) {
int tmpIdx = entry.getKey();
Clob clob = entry.getValue();
preparedStatement.setClob(tmpIdx, clob);
}
// for (Entry<Integer, Blob> entry : tmpBlobMap.entrySet()) {
// int tmpIdx = entry.getKey();
// Blob blob = entry.getValue();
// preparedStatement.setBlob(tmpIdx, blob.getBinaryStream());
// }
for (int tmpIdx : tmpBlobSet) {
File f = new File(String.format(TotomiConfigure.Tmp_Blob_file_Path_Format, tmpIdx)) ; // 图片文件
InputStream input = null ;
input = new FileInputStream(f) ;
preparedStatement.setBinaryStream(tmpIdx, input, (int)f.length()) ; // 设置输入流
}
preparedStatement.executeUpdate();
}
else {
checkString = insertSQL;
statement2.addBatch(insertSQL);
// System.out.println(insertSQL);
cnt ++;
if (cnt >= 1) {
cnt = 0;
statement2.executeBatch();
}
}
}
if (cnt > 0) {
statement2.executeBatch();
}
// // for test on real environment because data is too big for me to store !!
// statement2.execute(deleteTableSQL);
mySQLRecorder.updateSucceed(tableName);
} catch (Exception e) {
System.out.println("check String: " + checkString);
mySQLRecorder.updateFailed(tableName);
e.printStackTrace();
}
}
public static void main(String[] args) {
DbTransfer transfer = new DbTransfer();
// transfer.handle("TESTTB001");
// transfer.handleOneTable("act");
// transfer.getAllTableNames();
transfer.handle();
// transfer.handleOneTable("A00003_TH");
}
}
JDBC获得DB2表结构并且将表中数据脱敏后转移的程序示例的更多相关文章
- mysql ---复制表结构---创建新表
1.复制表结构及数据到新表CREATE TABLE 新表SELECT * FROM 旧表这种方法会将oldtable中所有的内容都拷贝过来,当然我们可以用delete from newtable;来删 ...
- (转载)根据数据字典表定义的表结构,生成创建表的SQL语句
<来源网址:http://www.delphifans.com/infoview/Article_221.html>根据数据字典表定义的表结构,生成创建表的SQL语句 //1. 类名:T ...
- mysql复制表数据或表结构到新表中
MySQL复制表数据到新表的几个步骤. 1.MySQL复制表结构及数据到新表 CREATE TABLE new_table SELECT * FROM old_table; 2.只复制表结构到新表 C ...
- powerdesigner 连接 Oracle ,并将表结构导入到powerdesigner中
powerdesigner 详细很多人都用过,很多人可能也有用来连接各种数据库以及从数据库中把表结构更新到powerdesigner的model中,或者将自己设计的表结构应用到数据库中.那么我今天就说 ...
- sql复制表结构及复制表数据
一.复制表结构 假设我们有一个数据表Person,有Id,FirstName,LastName,Weight,Height5个列,表结构可以参考这一篇.现在我们想创建一个新表叫People,表结构和P ...
- sql复制表结构,复制表内容语句
sql复制表结构,复制表内容语句 select * into b from a where 1<>1 select top 0 * into b from a insert into a ...
- linux mysql-workbench 创建与正式库表结构一样的表
先在本地创建数据库 字符集选择这个 创建数据库成功 创建与正式库一样的表 step1: 连接正式库,找到要生成的表,导出创建表的sql语句 step2: 找到本地数据库,选择表,在sql执行区域复制s ...
- Activiti数据库表结构(23张表5.*版本)
1 Activiti数据库表结构 1.1 数据库表名说明 Activiti工作流总共包含23张数据表,所有的表名默认以“ACT_”开头. 并且表名的第二部分用两个字母表明表的用例,而这个用 ...
- mysql复制表结构,复制表数据
MYSQL 复制表 show create table table_name:查看表的建表语句.该语句包含了原数据表的结构,索引等. 使用 SHOW CREATE TABLE 命令获取创建数据表(CR ...
随机推荐
- lvs原理及安装部署详解(参考)
LVS安装使用详解 摘至:http://www.cnblogs.com/MacoLee/p/5856858.html 简介 LVS是Linux Virtual Server的简称,也就是Linux虚拟 ...
- Java基础 String 裸暴力算法- 五个小练习
之间的博客,承上启下: Java基础 String/StringBuff 常用操作方法复习/内存分析 Java数组直接选择排序.sort()排序 Java基础 String 算法 - 五个练 ...
- VisualGC,JVMStat安装配置
通过VisualGC工具可以通过图形化方式查看JVM垃圾收集的情况. http://www.oracle.com/technetwork/java/jvmstat-142257.html 下载 htt ...
- js代码加这个<!--代码//-->
避免因为浏览器不支持js代码,而直接显示出来,以html注释的形式隐藏
- python自动华 (七)
Python自动化 [第七篇]:Python基础-面向对象高级语法.异常处理.Scoket开发基础 本节内容: 1. 面向对象高级语法部分 1.1 静态方法.类方法.属性方法 1.2 ...
- P3474 [POI2008]KUP-Plot purchase
思路:单调栈 提交:>5次 错因:单调栈写法有问题+前缀和写错 题解: 若有\(>=k\ \&\&\ <=2\times k\)的点,显然直接选他就行了. 否则,我们 ...
- 对象(Object)相关
详情参考 1.对象的表示方法 js原生提供Object构造函数.js中所有的对象都是Object的实例. 定义一个对象最简单的就是var obj = {}; ES6属性和方法允许简写.对象的super ...
- 下载文件设置header的filename要用ISO8859-1编码的原因
很多情况下,我们在写程序的时候都会把代码设置为UTF-8的编码,可以在下载文件设置filename的时候却有违常理,竟然设置编码格式为ISO8859-1,代码如下(如是英文的话就不需要这样处理了): ...
- python 使用流式游标 读取mysql怎么不会内存溢出
使用过java读取mysql大数据量的人应该都知道,如果查询时不开游标不设置一次性区大小的话,会一次性的把所有记录都拉取过来再进行后续操作,数据量一大就很容易出现OOM 如果用python去读取mys ...
- js中对象的输出顺序
前言:最近用for-in时,看到说for-in不能保证遍历的对象顺序,对此有些疑问,于是便研究了下,本文做简要说明. 现象 let obj = { a: 'a', b: 'b', 1: 1, 2: 2 ...