JAVA-MySQL与Oracle或者(Oracle与MySQL)之间相互拷贝数据
1、数据库信息
MySQL :5.6.38 Oracle:11.2.0.1.0
2、建表信息
MySQL:
CREATE TABLE cs (
id INT ,
cname VARCHAR (20),
phone VARCHAR (11)
) DEFAULT CHARSET = utf8 ;
Oracle:
create table cs
(
id number(10) ,
cname varchar2(50) not null,
phone varchar2(11) not null
);
3、MySQL执行命令
SELECT * FROM cs; 查询表数据
SHOW FULL COLUMNS FROM cs; 查看表字段字符集
DESC cs; 查看表结构
DROP TABLE cs; 删除表
DELETE FROM cs; 清空表
4、Oracle执行命令
SELECT * FROM cs; 查询表数据
DESC cs; 查看表结构
DROP TABLE cs; 删除表
DELETE FROM cs; 清空表
SELECT userenv('language') FROM DUAL; 查看字符集
5、准备验证测试数据插入表cs中(也可以先插入MySQL,反过来插入Oracle)
INSERT INTO cs VALUES(1,'李四','15398037986');
INSERT INTO cs VALUES(2,'张三','15398031324');
INSERT INTO cs VALUES(3,'王五','15691432979');
6、开始验证Oracle同步到MySQL(Java类如下),表名cs。
package oracle.mysql.com;
import java.sql.*;
/**
* 这是一个将Oracle数据库中的数据拷贝到MySQL数据库中的简单程序。
* 仅考虑NUMBER/CHAR/VARCHAR/CLOB/DATE/TIMESTAMP等字段类型。
* BLOB没有考虑(因为我的数据库中没有BLOB字段,无法测试)。 前提:两个数据库中都具有相关的表,且表结构相同,目标数据库中还不能存在冲突的数据。
*/
public class CopyOracle2MySQL {
// 源数据库,目标数据库的连接配置
private final String DEST_MYSQL_JDBC_URL = "jdbc:mysql://192.168.0.2:3306/cs?user=txytest&password=txytest123&useUnicode=true&characterEncoding=utf-8";
private final String SOURCE_JDBC_URL = "jdbc:oracle:thin:@localhost:1521:bdorcl";
private final String SOURCE_JDBC_USER = "community";
private final String SOURCE_JDBC_PASSWORD = "community123";
public void startImport() throws Exception {
// 创建到两个数据库的连接
Class.forName("org.gjt.mm.mysql.Driver");
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connDest = DriverManager.getConnection(DEST_MYSQL_JDBC_URL);
Connection connSource = DriverManager.getConnection(SOURCE_JDBC_URL, SOURCE_JDBC_USER, SOURCE_JDBC_PASSWORD);
try {
// 人工输入各表名(需要保证顺序,以确保有外键的表在主表之后插入数据)
importTable(connSource, connDest, "cs");
} finally {
// 自动关闭数据库资源
connDest.close();
connSource.close();
}
}
private void importTable(Connection connSource, Connection connDest, String tablename) throws Exception {
Statement stmt = null;
PreparedStatement pstmt = null;
try {
// 给PreparedStatement赋值,然后更新;如果是大数量的情况,可以考虑Batch处理。因为这里的数据量小,直接单条更新了。
// 打开源数据库中相关表
StringBuilder insertSQL = new StringBuilder();
insertSQL.append("insert into " + tablename + "(");
stmt = connSource.createStatement();
ResultSet rs = stmt.executeQuery("select * from " + tablename);
// 先计算目标数据库的PreparedStatement的SQL语句
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
for (int i = 1; i <= numberOfColumns; i++) {
insertSQL.append(rsmd.getColumnName(i) + ",");
}
insertSQL.deleteCharAt(insertSQL.length() - 1);
insertSQL.append(")values(");
for (int i = 1; i <= numberOfColumns; i++) {
insertSQL.append("?,");
}
insertSQL.deleteCharAt(insertSQL.length() - 1);
insertSQL.append(")");
System.out.println(insertSQL.toString());
// 计数
int count = 0;
// 每多少条记录提交 一次,以提高效率
int batchCount = 1000;
pstmt = connDest.prepareStatement(insertSQL.toString());
while (rs.next()) {
pstmt.clearParameters();
for (int i = 1; i <= numberOfColumns; i++) {
if (rsmd.getColumnType(i) == java.sql.Types.NUMERIC) {
pstmt.setInt(i, rs.getInt(i));
} else if (rsmd.getColumnType(i) == java.sql.Types.DOUBLE) {
pstmt.setDouble(i, rs.getDouble(i));
} else if (rsmd.getColumnType(i) == java.sql.Types.CHAR
|| rsmd.getColumnType(i) == java.sql.Types.VARCHAR
|| rsmd.getColumnType(i) == java.sql.Types.CLOB) {
pstmt.setString(i, rs.getString(i));
} else if (rsmd.getColumnType(i) == java.sql.Types.DATE) {
pstmt.setDate(i, rs.getDate(i));
} else if (rsmd.getColumnType(i) == java.sql.Types.TIMESTAMP) {
pstmt.setTimestamp(i, rs.getTimestamp(i));
} else {
pstmt.setObject(i, rs.getObject(i));
}
}
pstmt.addBatch();
// 输出统计信息
count++;
if (count % batchCount == 0) {
// 若干条提交一次
System.out.println("---------------正在更新数据库--------------------");
pstmt.executeBatch();
System.out.println(count + "正在更新");
}
}
if (count % batchCount != 0) {
// 最后提交一次
System.out.println("---------------最后一次更新数据库--------------------");
pstmt.executeBatch();
System.out.println(count + "已完成");
}
rs.close();
} finally {
if (stmt != null)
stmt.close();
if (pstmt != null)
pstmt.close();
}
}
public static void main(String[] args) throws Exception {
CopyOracle2MySQL ins = new CopyOracle2MySQL();
ins.startImport();
}
}
7、开始验证MySQL同步到Oracle(Java类如下),表名cs。
package mysql.oracle.com;
import java.sql.*;
/**
* 从MySQL数据库拷贝表数据到Oracle数据库中的程序。 前提:两个数据库中都具有相关的表,且表结构相同,目标数据库中还不能存在冲突的数据。
*/
public class CopyMySQL2Oracle {
// 源数据库,目标数据库的连接配置
String mysql_jdbc_url = "jdbc:mysql://192.168.0.2:3306/cs?user=txytest&password=txytest123&useUnicode=true&characterEncoding=gb2312";
String jdbc_url = "jdbc:oracle:thin:@localhost:1521:bdorcl";
String jdbc_user = "community";
String jdbc_password = "community123";
public void startProcess(String tableName) throws Exception {
// 创建到两个数据库的连接
Class.forName("org.gjt.mm.mysql.Driver");
Connection connSource = DriverManager.getConnection(mysql_jdbc_url);
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connDest = DriverManager.getConnection(jdbc_url, jdbc_user, jdbc_password);
// 打开源数据库中相关表
StringBuilder sb = new StringBuilder();
sb.append("insert into " + tableName + "(");
Statement stmt = connSource.createStatement();
ResultSet rs = stmt.executeQuery("select * from " + tableName);
// 显示共计有多少条记录
rs.last();
System.out.println(tableName + "表共计有:" + rs.getRow() + "条记录,正在处理......");
rs.beforeFirst();
// 先计算目标数据库的PreparedStatement的SQL语句
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
for (int i = 1; i <= numberOfColumns; i++) {
sb.append(rsmd.getColumnName(i) + ",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")values(");
for (int i = 1; i <= numberOfColumns; i++) {
sb.append("?,");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
System.out.println(sb.toString());
// 给PreparedStatement赋值,然后更新;如果是大数量的情况,可以考虑Batch处理。因为这里的数据量小,直接单条更新了。
PreparedStatement pstmt = connDest.prepareStatement(sb.toString());
while (rs.next()) {
for (int i = 1; i <= numberOfColumns; i++) {
pstmt.setObject(i, rs.getObject(i));
}
pstmt.executeUpdate();
}
System.out.print("---更新完成---");
// 关闭各资源
rs.close();
stmt.close();
pstmt.close();
connSource.close();
connDest.close();
}
public static void main(String[] args) throws Exception {
CopyMySQL2Oracle ins = new CopyMySQL2Oracle();
ins.startProcess("cs");
}
}
8、以上准备完成之后,即可运行验证。