Java對比兩個資料庫中的表和欄位,寫個冷門的東西

來源:互聯網
上載者:User

標籤:

Java對比兩個資料庫中的表和欄位,寫個冷門的東西

轉載的 來源網路

 

目前所在的項目組距離下個版本上線已經很近了,就面臨了一個問題:開發人員在開發庫上根據需要增加資料表、資料欄位、或者變更了欄位類型或者欄位長度等等。

由於時間比較緊迫,導致在開發過程中不可能一一把DDL資料庫指令碼記錄下來,在比較大的項目中,比如我所在項目開發的系統大概包含了800張左右的表,欄位上10000個的情況下,人工處理明顯不可行,所以我們就得通過程式來判斷比對,哪些是我們需要新增加的表,哪些是我們需要新增加的欄位,哪些是我們需要修改的欄位。

因為我開發的項目是為銀行工作的,所以資料量無疑很大,所以這個Java類可以用於幾乎大多數情況了,當前情況是正在啟動並執行生產伺服器上有個資料庫-->生產庫,我們開發人員伺服器上有個資料庫-->開發庫,就需要我們將兩庫差異對比出來,我差不多花了1個小時寫了下面幾個類,運行一下就可以將差異化的地方寫入檔案中,便於後續寫DDL指令碼處理。

首先是一個 Table 類,代表了我們資料庫中的一張表,其中存在String類型的表名、和存放若干個各種欄位的HashMap()

    Java  
1234567891011121314151617181920212223242526 package test;import java.util.HashMap;public class Table {public String tableName;public HashMap columns = new HashMap(); public Table(String tableName) {this.tableName = tableName;} public String getTableName() {return tableName;} public void setTableName(String tableName) {this.tableName = tableName;} public HashMap getColumns() {return columns;} public void setColumns(HashMap columns) {this.columns = columns;}}

接著就是一個 Column 類,代表了資料庫中的一個欄位,其中屬性就是欄位名、欄位類型、欄位長度,當然可以根據自己的需求加入更多要素

    Java  
123456789101112131415161718192021222324252627282930 package test;public class Column {public String columnName;public String dataType;public int length; public Column(String columnName, String dataType, int length) {this.columnName = columnName;this.dataType = dataType;this.length = length;}public String getColumnName() {return columnName;}public void setColumnName(String columnName) {this.columnName = columnName;}public String getDataType() {return dataType;}public void setDataType(String dataType) {this.dataType = dataType;}public int getLength() {return length;}public void setLength(int length) {this.length = length;}}

其實這個方法完全可以不用上面兩個類的,但是為了寫起來理解方便,所以就用了,執行效率其實還不錯,幾百張表幾秒鐘就跑完了

下面是實現這個需求的主要類,寫出來的主要目的就是希望能幫我改進一下,畢竟自己寫程式沒有太多的設計理念和大局觀,希望能者修改修改:

    Java  
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 package test;package test; import java.io.File;import java.io.FileOutputStream;import java.io.OutputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.HashMap;import java.util.Iterator;import java.util.Map; import com.amarsoft.are.sql.ASResultSet;import com.amarsoft.are.sql.Transaction;import com.amarsoft.are.util.DataConvert; public class CompareTable { public static StringBuffer[] sb = { new StringBuffer(), new StringBuffer(),new StringBuffer(), new StringBuffer(), new StringBuffer(),new StringBuffer() }; public static Transaction getTransaction_product() throws Exception {Class.forName("oracle.jdbc.driver.OracleDriver");Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.1:1621:orcl", "demo1", "demo1");if (conn != null)System.out.println("資料庫載入成功!");Transaction transaction = new Transaction(conn);return transaction;} public static Transaction getTransaction_develop() throws Exception {Class.forName("oracle.jdbc.driver.OracleDriver");Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.2:1621:orcl", "demo2", "demo2");if (conn != null)System.out.println("資料庫載入成功!");Transaction transaction = new Transaction(conn);return transaction;} public static void main(String[] args) throws Exception {compareTables(); // 比較資料庫writeFile(); // 寫入檔案}   public static void compareTables() throws Exception { // 生產資料庫連接Transaction trans_product = getTransaction_product();Map<</SPAN>String, Table> map_product = getTables(trans_product); // 開發資料庫連接Transaction trans_develop = getTransaction_develop();Map<</SPAN>String, Table> map_develop = getTables(trans_develop); // 遍曆開發庫Mapfor (Iterator iter_table = map_develop.keySet().iterator(); iter_table.hasNext();) {String key_table = (String) iter_table.next();Table table_develop = map_develop.get(key_table);// 獲得開發庫中的表Table table_product = map_product.get(key_table);// 嘗試從生產庫中獲得同名表if (table_product == null) { // 如果獲得表為空白,說明開發存在,生產不存在append(table_develop, null, 2);} else { // 表相同,判斷欄位、欄位類型、欄位長度for (Iterator iter_column = table_develop.columns.keySet().iterator(); iter_column.hasNext();) {String key_column = (String) iter_column.next();Column column_develop = table_develop.columns.get(key_column);// 獲得開發庫中的列Column column_product = table_product.columns.get(key_column);// 嘗試從生產庫中獲得同名列if (column_product == null) {// 如果列名為空白,說明開發存在,生產不存在append(table_develop, column_develop, 4);} else {// 說明兩者都存在if (!column_develop.dataType.equals(column_product.dataType))// 欄位類型不一致append(table_develop, column_develop, 5);if (column_develop.length != column_product.length)// 欄位長度不一致append(table_develop, column_develop, 6);}}}} // 遍曆生產庫Mapfor (Iterator iter_table = map_product.keySet().iterator(); iter_table.hasNext();) {String key_table = (String) iter_table.next();Table table_product = map_product.get(key_table);// 嘗試從生產庫中獲得同名表Table table_develop = map_develop.get(key_table);// 獲得開發庫中的表if (table_develop == null) { // 如果獲得表為空白,說明開發存在,生產不存在append(table_product, null, 1);} else { // 表相同,判斷欄位、欄位類型、欄位長度for (Iterator iter_column = table_product.columns.keySet().iterator(); iter_column.hasNext();) {String key_column = (String) iter_column.next();Column column_product = table_product.columns.get(key_column);// 獲得生產庫中的列Column column_develop = table_develop.columns.get(key_column);// 嘗試從開發庫中獲得同名列if (column_develop == null) {// 如果列名為空白,說明生產存在,開發不存在append(table_product, column_product, 3);}}}}}  public static Map<</SPAN>String, Table> getTables(Transaction transaction)throws Exception { String sSql = " select table_name,Column_Name,Data_Type,"+ " DECODE(DATA_TYPE,‘NUMBER‘,DATA_PRECISION,‘VARCHAR2‘,"+ " DATA_LENGTH,‘VARCHAR‘,DATA_LENGTH,‘CHAR‘,DATA_LENGTH,0) Length,"+ " NVL(DATA_SCALE, 0) SCALE,DECODE(NULLABLE, ‘N‘, ‘1‘, ‘0‘) NULLABLE "+ " from user_tab_columns where 1=1 Order By table_name,column_name"; ASResultSet rs = transaction.getASResultSet(sSql); Map<</SPAN>String, Table> map = new HashMap<</SPAN>String, Table>(); String tableName = "";Table table = null;while (rs.next()) {if (!tableName.equals(rs.getString("table_name"))) {// 一張新表tableName = rs.getString("table_name");table = new Table(tableName);Column column = new Column(rs.getString("Column_Name"),rs.getString("Data_Type"), rs.getInt("Length"));table.columns.put(column.columnName, column);map.put(rs.getString("table_name"), table);} else {// 已存在的表,增加欄位Column column = new Column(rs.getString("Column_Name"),rs.getString("Data_Type"), rs.getInt("Length"));table.columns.put(column.columnName, column);}}if (null != rs)rs.close();transaction.finalize();return map;}  public static void append(Table table, Column column, int flag)throws Exception {switch (flag) {case 1:System.out.println("1、生產存在,開發不存在的表:" + table.getTableName());// 跳過sb[0].append(table.getTableName() + "\n");break;case 2:System.out.println("2、生產不存在,開發存在的表:" + table.getTableName());// 需要人工判斷指令碼sb[1].append(table.getTableName() + "\n");break;case 3:System.out.println("3、生產存在,開發不存在的欄位:" + table.getTableName()+ " | " + column.getColumnName());// 需人工判斷如何處理sb[2].append(table.getTableName() + " | " + column.getColumnName()+ "\n");break;case 4:System.out.println("4、生產不存在,開發存在的欄位:" + table.getTableName()+ " | " + column.getColumnName());// 需要人工判斷指令碼sb[3].append(table.getTableName() + " | " + column.getColumnName()+ "\n");break;case 5:System.out.println("5、表和欄位都相同,但欄位類型不同的內容:" + table.getTableName()+ " | " + column.getColumnName() + " | "+ column.getDataType());// 需要人工判斷指令碼sb[4].append(table.getTableName() + " | " + column.getColumnName()+ " | " + column.getDataType() + "\n");break;case 6:System.out.println("6、表和欄位、欄位類型都相同,但欄位長度不同的內容:"+ table.getTableName() + " | " + column.getColumnName()+ " | " + column.getLength());// 需要人工判斷指令碼sb[5].append(table.getTableName() + " | " + column.getColumnName()+ " | " + column.getLength() + "\n");break;}}  public static void writeFile() throws Exception {String[] fileName = { "D://table//生產存在,開發不存在的表.txt","D://table//生產不存在,開發存在的表.txt", "D://table//生產存在,開發不存在的欄位.txt","D://table//生產不存在,開發存在的欄位.txt","D://table//表和欄位都相同,但欄位類型不同的內容.txt","D://table//表和欄位、欄位類型都相同,但欄位長度不同的內容.txt" }; for (int i = 0; i <</SPAN> fileName.length; i++) {File file = new File(fileName[i]);OutputStream os = new FileOutputStream(file);os.write(sb[i].toString().getBytes());os.flush();os.close();}}}

尾聲:整個程式其實並不複雜,感覺被我寫得有些累贅了,希望以後能精簡一點吧

分享:   

Java對比兩個資料庫中的表和欄位,寫個冷門的東西

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.