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 ...
随机推荐
- python_并发编程——进程池
1.进程池 from multiprocessing import Pool def func(n): for i in range(10): print(n+1) if __name__ == '_ ...
- js中当call或者apply传入的第一个参数是null/undefined时,js函数内执行的上下文环境是什么?
在js中我们都知道call/apply,还有比较少用的bind;传入的第一个参数都是改变函数当前上下文对象; call/apply区别在于传的参数不同,一个是已逗号分隔字符串,一个以数组形式.而bin ...
- Codeforces Round #551 (Div. 2) F. Serval and Bonus Problem (DP/FFT)
yyb大佬的博客 这线段期望好神啊... 还有O(nlogn)FFTO(nlogn)FFTO(nlogn)FFT的做法 Freopen大佬的博客 本蒟蒻只会O(n2)O(n^2)O(n2) CODE ...
- 【转】解决 canvas 在高清屏中绘制模糊的问题
来源: http://www.css88.com/archives/9297 使用 canvas 绘制图片或者是文字在 Retina 屏中会非常模糊.如图: 因为 canvas 不是矢量图,而是像图片 ...
- 第八章 用SQL语句操作数
--切换数据库:手动切换和命令切换 use MySchool --向Student表中插入数据 --语法:INSERT [INTO] 表名 (列名) VALUES (值列表) --注意事项: --1. ...
- linux笔试题
1. cron 后台常驻程序 (daemon) 用于: A. 负责文件在网络中的共享 B. 管理打印子系统 C. 跟踪管理系统信息和错误 D. 管理系统日常任务的调度 2. 在大多数Linux发行版本 ...
- Asteroids POJ - 3041 【最小点覆盖集】
Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N g ...
- SQL Server report server使用
1.配置share point網站來改動報表 打開Reporting Servers Configuration Manager,裏面有Web Service URL(http://loca ...
- K8S中Pods
什么是Pod 一个Pod(就像一群鲸鱼,或者一个豌豆夹)相当于一个共享context的配置组,在同一个context下,应用可能还会有独立的cgroup隔离机制,一个Pod是一个容器环境下的“逻辑主机 ...
- busTrace VS HW protocol analyzer - 好东西推荐
最近在找PCIe/NVMe协议分析仪,发现一款软件分析仪:busTRACE,非常不错的工具,对于从事协议开发的同胞们,是个福利,下面把硬件和软件两种分析仪的各自的优势比较了一下(来自busTrace文 ...