zoukankan      html  css  js  c++  java
  • 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 的话,也是类似的思路,修改一下程序即可!

    欢迎批评、指正、交流!

  • 相关阅读:
    AJAX 基础知识
    jQuery知识点总结
    css基础应用总结
    javascript 总结
    找回密码-博客园
    centerOS 7 安装MySql
    java leetcode TreeNode类、ListNode类的实现
    iOS StatusBar状态栏文字颜色更改
    使用Jmeter压力测试工具测试
    安装node.js
  • 原文地址:https://www.cnblogs.com/gyyyblog/p/12626829.html
Copyright © 2011-2022 走看看