將表中的資料複製到另一個數據庫的表中
阿新 • • 發佈:2018-12-20
1. 在 src 目錄下建立 jdbc.properties
#Oracle oracle.driver=oracle.jdbc.driver.OracleDriver oracle.jdbcUrl=jdbc:oracle:thin:@localhost:1521:orcl oracle.user=scott oracle.password=tiger #MySQL mysql.driver=com.mysql.jdbc.Driver mysql.jdbcUrl=jdbc:mysql://localhost:3306/test mysql.user=root mysql.password=root #SQL Server sqlserver.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver sqlserver.jdbcUrl=jdbc:sqlserver://localhost:1433;DatabaseName=tempdb sqlserver.user=sa sqlserver.password=123456
2. 編寫 JdbcUtils 工具類
import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; public class JdbcUtils { public static enum DatabaseType { Oracle("oracle"), SQL_Server("sqlserver"), MySQL("mysql"); private String name; private DatabaseType(String name) { this.name = name; } public String getName() { return name; } }; private static Properties props; static { try { InputStream in = Thread.currentThread() .getContextClassLoader() .getResourceAsStream("jdbc.properties"); props = new Properties(); props.load(in); } catch (IOException e) { throw new ExceptionInInitializerError(e); } } /** * 獲取資料庫連線 * @param type 要操作的資料庫 * @return * @throws Exception */ public static Connection getConnection(DatabaseType type) throws Exception { Class.forName(props.getProperty(type.getName() + ".driver")); String jdbcUrl = props.getProperty(type.getName() + ".jdbcUrl"); String user = props.getProperty(type.getName() + ".user"); String password = props.getProperty(type.getName() + ".password"); return DriverManager.getConnection(jdbcUrl, user, password); } /** * 將查詢的資料複製到另一個數據庫的表中,要求兩張表的欄位名,欄位型別完全相同。 * @param src 要查詢的資料庫 * @param sql 要查詢的 SQL * @param dest 目標資料庫 * @param destTableName 目標表名稱 * @return */ public static int[] copy(DatabaseType src, String sql, DatabaseType dest, String destTableName ) { int count[] = new int[0]; List<Map<String,Object>> query = JdbcUtils.query(DatabaseType.Oracle, sql); String insertSql = "insert into %s(%s) values(%s)"; StringBuilder key = new StringBuilder(); StringBuilder value = new StringBuilder(); List<String> columns = new ArrayList<>(); List<List<Object>> params = new ArrayList<>(); if(query.size() > 0) { for(String column : query.get(0).keySet()) { key.append(column).append(","); value.append("?,"); columns.add(column); } insertSql = String.format(insertSql, destTableName, key.substring(0, key.length()-1).toString(), value.substring(0, value.length()-1).toString()); for (Map<String, Object> map : query) { List<Object> param = new ArrayList<>(); for (String column : columns) { param.add(map.get(column)); } params.add(param); } count = JdbcUtils.executeBatch(DatabaseType.MySQL, insertSql, params); } return count; } /** * 批量執行多條 SQL 語句 * @param type 要執行的資料庫 * @param sqls SQL 語句 * @return */ public static int[] executeBatch(DatabaseType type, List<String> sqls) { int count[] = new int[0]; Connection conn = null; Statement stmt = null; try { conn = getConnection(type); boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); stmt = conn.createStatement(); for (String sql : sqls) { stmt.addBatch(sql); } count = stmt.executeBatch(); conn.commit(); conn.setAutoCommit(autoCommit); } catch (Exception e) { throw new RuntimeException(e); } finally { closeStatement(stmt); closeConnection(conn); } return count; } /** * 批量執行一個 SQL 語句,可以傳不同的引數 * @param type 要執行的資料庫 * @param sql SQL 語句 * @param params 引數列表 * @return */ public static int[] executeBatch(DatabaseType type, String sql, List<List<Object>> params) { int count[] = new int[0]; Connection conn = null; PreparedStatement pst = null; try { conn = getConnection(type); boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); pst = conn.prepareStatement(sql); for (List<Object> list : params) { for(int i = 0; i < list.size(); i++) { pst.setObject(i + 1, list.get(i)); } pst.addBatch(); } count = pst.executeBatch(); conn.commit(); conn.setAutoCommit(autoCommit); } catch (Exception e) { throw new RuntimeException(e); } finally { closeStatement(pst); closeConnection(conn); } return count; } /** * 執行單條 SQL 語句 * @param type 要執行的資料庫 * @param sql SQL 語句 * @param args 引數列表 * @return */ public static int execute(DatabaseType type, String sql, Object...args) { int count = 0; Connection conn = null; PreparedStatement pst = null; try { conn = getConnection(type); boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); pst = conn.prepareStatement(sql); for(int i = 0; i < args.length; i++) { pst.setObject(i + 1, args[i]); } count = pst.executeUpdate(); conn.commit(); conn.setAutoCommit(autoCommit); } catch (Exception e) { throw new RuntimeException(e); } finally { closeStatement(pst); closeConnection(conn); } return count; } /** * 查詢資料並封裝到 List 集合中 * @param type 要查詢的資料庫 * @param sql SQL 語句 * @param args 引數列表 * @return List<Map<欄位名, 值>> */ public static List<Map<String, Object>> query(DatabaseType type, String sql, Object...args) { List<Map<String, Object>> result = new ArrayList<>(); Connection conn = null; PreparedStatement pst = null; ResultSet rs = null; try { conn = getConnection(type); pst = conn.prepareStatement(sql); for(int i = 0; i < args.length; i++) { pst.setObject(i + 1, args[i]); } rs = pst.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); List<String> columns = new ArrayList<>(columnCount); for(int i = 1; i <= columnCount; i++) { columns.add(rsmd.getColumnName(i)); // 欄位名 } while(rs.next()) { Map<String, Object> map = new HashMap<>(); for (String column : columns) { map.put(column, rs.getObject(column)); } result.add(map); } } catch (Exception e) { throw new RuntimeException(e); } finally { closeStatement(pst); closeConnection(conn); } return result; } /** * 關閉 Statement * @param stmt * @return */ public static boolean closeStatement(Statement stmt) { boolean flag = true; if(stmt != null) { try { stmt.close(); } catch (SQLException e) { flag = false; } } return flag; } /** * 關閉 ResultSet * @param rs * @return */ public static boolean closeResultSet(ResultSet rs) { boolean flag = true; if(rs != null) { try { rs.close(); } catch (SQLException e) { flag = false; } } return flag; } /** * 關閉 Connection * @param conn * @return */ public static boolean closeConnection(Connection conn) { boolean flag = true; if(conn != null) { try { conn.close(); } catch (SQLException e) { flag = false; } } return flag; } }
3. 編寫測試程式碼
import demo.JdbcUtils.DatabaseType; public class Test { public static void main(String[] args) throws Exception { // 將 oracle 中的 scott.emp 表中的資料插入到 mysql 的 emp 表中 long start = System.currentTimeMillis(); String sql = "select a.* from emp a"; int[] count = JdbcUtils.copy(DatabaseType.Oracle, sql, DatabaseType.MySQL, "emp"); long end = System.currentTimeMillis(); System.out.println(String.format("用時:%s, count.length = %s", end - start, count.length)); } }
4. 執行結果
用時:1442, count.length = 14