Java實現Oracle拷貝數據插入到MySQL


前言

在一個項目中,公司讓做了兩個版本.netjava.net用的是Oraclejava用的mysql,表中字段定義都一樣,后來打算上線時用Java版本,但需要保留Oracle數據,並合並到MySQL中,所以就衍生了這篇文章。
在網上看到有人用一些阿里的或者其他的什么工具來做,總有各種各樣的問題,所以就自己簡單寫個程序,也不復雜,但也有缺點。
比如


無法判斷當前數據是否存在、無法排除目標數據庫中沒有的字段,數據類型沒有轉換完全(因為我沒用到)等
如果達不到您的需求就不必看代碼了,避免浪費時間,如果您有什么好的以上問題的解決辦法和代碼完善,歡迎留言或加我qq探討,聯系方式在文章末尾!

正片

package com.zz.spxt.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;


/**
* @desprition 拷貝oracle數據拷貝到mysql工具
* 僅考慮NUMBER/CHAR/VARCHAR/CLOB/DATE/TIMESTAMP數據類型
*
* 注意: 兩個數據庫中具有表結構相同的相關表,目標數據庫中不能有沖突數據
* @author 楊洋
*/
public class CopyOracle2Mysql {
    private static Logger logger = LoggerFactory.getLogger("insert sql");

    /**
    * 源數據庫、目標數據庫連接配置
    */
    private static final String MYSQL_JDBC_URL = "jdbc:mysql://localhost:3306/test?" +
        "user=root&password=test&serverTimezone=GMT%2B8&useSSL=false&useUnicode=true&characterEncoding=UTF-8";
    private static final String ORACLE_JDBC_URL = "jdbc:oracle:thin:@10.0.10.225:1521/orclpdb";
    private static final String ORACLE_JDBC_USER = "GJSP";
    private static final String ORACLE_JDBC_PASSWORD = "zz";
    private static final String TARGET_DATABASE = "zzz";

    public void startImport() throws Exception {
        // 創建數據庫連接
        Class.forName("com.p6spy.engine.spy.P6SpyDriver");
        Class.forName("oracle.jdbc.driver.OracleDriver");

        Connection connectMysql = DriverManager.getConnection(MYSQL_JDBC_URL);
        Connection connectOracle = DriverManager.getConnection(ORACLE_JDBC_URL,
                ORACLE_JDBC_USER, ORACLE_JDBC_PASSWORD);

        // 查詢出當前用戶下面所有的表,依次處理(有外鍵或者指定特定表數據,需手動輸入,沒有的話可以執行自動程序)
        try {
            // 添加事務
            connectMysql.setAutoCommit(false);
            // 1. 自動運行
            // Statement statement = connectOracle.createStatement();
            // ResultSet rs = statement.executeQuery("select TABLE_NAME from USER_TABLES");
            // while (rs.next()){
            // try {
            // importTable(connectOracle,connectMysql,rs.getString("TABLE_NAME"));
            // } catch (Exception e){
            // e.printStackTrace();
            // }
            // }
            // rs.close();
            // statement.close();
            // 2. 自己輸入表名(如果有外鍵,需要注意順序,確保有外鍵的表在主表之后插入數據)
            importTable(connectOracle, connectMysql, "b01_spgl_dfxmsplcxxb");
        } finally {
            connectMysql.close();
            connectOracle.close();
        }
    }

    private void importTable(Connection connectOracle, Connection connectMysql,
        String tableName) throws SQLException {
        Statement stmt = null;
        PreparedStatement pstmt = null;

        try {
            // 給PreparedStatement賦值,然后更新
            // 1. 打開源數據庫中相關表,拼接插入語句
            StringBuilder insertSql = new StringBuilder();

            // 如果表名不一致就自己手動替換,那也就只能一個表一個表拷貝,這邊默認一致
            insertSql.append("insert into ").append(tableName).append("(");
            stmt = connectOracle.createStatement();

            ResultSet rs = stmt.executeQuery("select * from " + tableName);
            ResultSetMetaData rsmd = rs.getMetaData();
            int numberOfColumns = rsmd.getColumnCount();

            for (int i = 1; i < numberOfColumns+1; i++) {
                insertSql.append(rsmd.getColumnName(i)).append(",");
            }

            insertSql.deleteCharAt(insertSql.length() - 1);
            insertSql.append(")values(");

            for (int i = 1; i < numberOfColumns+1; i++) {
                insertSql.append("?,");
            }

            insertSql.deleteCharAt(insertSql.length() - 1);
            insertSql.append(")");
            logger.info(insertSql.toString());

            // 計數器
            int count = 0;

            // 設定多少條記錄提交一次
            int batchCount = 1000;
            pstmt = connectMysql.prepareStatement(insertSql.toString());

            while (rs.next()) {
                pstmt.clearParameters();
                // 設置第一條即主鍵為null,讓其自增(如果有設置不是第一列為主鍵,那你自己看着改吧。。)
                pstmt.setNull(1, rs.getInt(1));

                for (int i = 2; i < numberOfColumns+1; i++) {
                    if (rsmd.getColumnType(i) == Types.NUMERIC) {
                        // 2
                        pstmt.setInt(i, rs.getInt(i));
                    } else if (rsmd.getColumnType(i) == Types.DOUBLE) {
                        // 8
                        pstmt.setDouble(i, rs.getDouble(i));
                    } else if ((rsmd.getColumnType(i) == Types.VARCHAR) ||
                            (rsmd.getColumnType(i) == Types.CHAR)) {
                        // 12 || 1
                        pstmt.setString(i, rs.getString(i));
                    } else if (rsmd.getColumnType(i) == Types.DATE) {
                        // 91
                        pstmt.setDate(i, rs.getDate(i));
                    } else if (rsmd.getColumnType(i) == Types.TIMESTAMP) {
                        // 93
                        pstmt.setTimestamp(i, rs.getTimestamp(i));
                    } else {
                        pstmt.setObject(i, rs.getObject(i));
                    }
                }

                pstmt.addBatch();
                // 輸出統計信息
                count++;

                if ((count % batchCount) == 0) {
                    logger.info("---------------正在更新數據庫--------------------");
                    pstmt.executeBatch();
                    logger.info(String.valueOf(count));
                }
            }

            if ((count % batchCount) != 0) {
                // 最后一次提交
                logger.info("---------------最后一次更新數據庫--------------------");
                pstmt.executeBatch();
                logger.info("插入".concat(String.valueOf(count)).concat("條數據"));
            }
            // 提交事務,設置事務默認值
            connectMysql.commit();
            connectMysql.setAutoCommit(true);
            rs.close();
        } catch (SQLException e) {
            // 如果失敗事務回滾
            connectMysql.rollback();
            logger.error(e.toString());
        } 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();
    }
}

如果需要mysqlOracle 的話,也是類似的思路,修改一下程序即可!

歡迎批評、指正、交流!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM