簡體   English   中英

比較Java中的兩個表

[英]Compare two tables in Java

我必須比較兩個表,並告訴用戶兩個表之間的區別是什么。

表格1

------+---------
|Code | Label   |  
------+---------  
|a1   | a1text  |  
------+---------  
|b1   | b1text  |  
------+---------  
|c1   | bartext1|  
------+---------  
|e1   | foo     |  
-----+--------- 

表2

------+---------  
|Code | Label   |  
------+---------  
|a1   | a1text  |  
------+---------  
|b1   | b2text  |  
------+---------  
|d1   | bartext2|  
------+---------  
|f1   | bar     |  
------+--------- 

比較信息
如表1所示,代碼c1標簽為bartext1 ,代碼d1標簽為bartext2 他們是相同的期望最后一個角色。 我必須在報告中輸入相同的字符,除了最后一個字符。 表中的行很少,可能有多余的單詞或特殊字符,並且其位置在任何地方。 我必須以某種方式在報告中告訴兩個標簽相同,但是期望單詞缺失或其中一個有特殊字符。代碼在報告中並不重要。

更多信息
此數據來自第三方。代碼始終是唯一的,它們不是重復的代碼。 兩個代碼可能具有類似的值,例如

代碼 標簽

ER4 | 我有個兄弟

WE3 | 我有個兄弟

預期輸出應為

  1. 兩個表中的標簽不同。 Table1標簽為:b1text,而Tabl2標簽為:b2text。
  2. 兩個表中的標簽不同。 Table1標簽為:bartext1,而Tabl2標簽為:bartext2。
  3. 表2中缺少標簽foo。
  4. 表1中缺少標簽欄。

這對我有用,請隨時添加鹽調味:

public final class ComparisonTest {

@Test
public void compare() throws Exception {
    String url = "your.url";
    String user = "your.user";
    String password = "your.password";
    // I am using Oracle here, but you can use any database
    Connection connection = getConnection(url, user, password, OracleDriver.class);

    ResultSet sourceResultSet = getResultSet(connection, "first_table");
    ResultSet targetResultSet = getResultSet(connection, "second_table");
    Map<Long, String> sourceIdHash = new HashMap<Long, String>();
    Map<Long, String> targetIdHash = new HashMap<Long, String>();

    try {
        long rows = 0;
        do {
            if (sourceResultSet.next()) {
                if (targetResultSet.next()) {
                    // Compare the lines
                    long sourceHash = hash(getRowValues(sourceResultSet, sourceResultSet.getMetaData()));
                    long targetHash = hash(getRowValues(targetResultSet, targetResultSet.getMetaData()));

                    sourceIdHash.put(sourceHash, sourceResultSet.getString(1));
                    targetIdHash.put(targetHash, targetResultSet.getString(1));

                    if (targetIdHash.containsKey(sourceHash)) {
                        targetIdHash.remove(sourceHash);
                        sourceIdHash.remove(sourceHash);
                    }
                    if (sourceIdHash.containsKey(targetHash)) {
                        sourceIdHash.remove(targetHash);
                        targetIdHash.remove(targetHash);
                    }
                } else {
                    // Add the source row
                    long sourceHash = hash(getRowValues(sourceResultSet, sourceResultSet.getMetaData()));
                    sourceIdHash.put(sourceHash, sourceResultSet.getString(1));
                }
            } else {
                if (targetResultSet.next()) {
                    // Add the target row
                    long targetHash = hash(getRowValues(targetResultSet, targetResultSet.getMetaData()));
                    targetIdHash.put(targetHash, targetResultSet.getString(1));
                } else {
                    break;
                }
            }
            if (rows++ % 10000 == 0) {
                System.out.println("Rows : " + rows);
            }
        } while (true);
    } finally {
        closeAll(sourceResultSet);
        closeAll(targetResultSet);
    }

    for (final Map.Entry<Long, String> mapEntry : sourceIdHash.entrySet()) {
        if (targetIdHash.containsKey(mapEntry.getKey())) {
            targetIdHash.remove(mapEntry.getKey());
            continue;
        }
        System.out.println("Not in target : " + mapEntry.getValue());
    }
    for (final Map.Entry<Long, String> mapEntry : targetIdHash.entrySet()) {
        if (sourceIdHash.containsKey(mapEntry.getKey())) {
            sourceIdHash.remove(mapEntry.getKey());
            continue;
        }
        System.out.println("Not in source : " + mapEntry.getValue());
    }

    System.out.println("In source and not target : " + sourceIdHash.size());
    System.out.println("In target and not source : " + targetIdHash.size());
}

private ResultSet getResultSet(final Connection connection, final String tableName) {
    String query = "select * from " + tableName + " order by pdb_key, organization_code, service_littera, day, resource_category";
    return executeQuery(connection, query);
}

private Object[] getRowValues(final ResultSet resultSet, final ResultSetMetaData resultSetMetaData) throws SQLException {
    List<Object> rowValues = new ArrayList<Object>();
    for (int i = 2; i < resultSetMetaData.getColumnCount(); i++) {
        rowValues.add(resultSet.getObject(i));
    }
    return rowValues.toArray(new Object[rowValues.size()]);
}

private final Connection getConnection(final String url, final String user, final String password, final Class<? extends Driver> driverClass) {
    try {
        DriverManager.registerDriver(driverClass.newInstance());
        return DriverManager.getConnection(url, user, password);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private final ResultSet executeQuery(final Connection connection, final String query) {
    try {
        return connection.createStatement().executeQuery(query);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

private final Long hash(final Object... objects) {
    StringBuilder builder = new StringBuilder();
    for (Object object : objects) {
        builder.append(object);
    }
    return hash(builder.toString());
}

public Long hash(final String string) {
    // Must be prime of course
    long seed = 131; // 31 131 1313 13131 131313 etc..
    long hash = 0;
    char[] chars = string.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        hash = (hash * seed) + chars[i];
    }
    return Long.valueOf(Math.abs(hash));
}

private void closeAll(final ResultSet resultSet) {
    Statement statement = null;
    Connection connection = null;
    try {
        if (resultSet != null) {
            statement = resultSet.getStatement();
        }
        if (statement != null) {
            connection = statement.getConnection();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    close(resultSet);
    close(statement);
    close(connection);
}

private void close(final Statement statement) {
    if (statement == null) {
        return;
    }
    try {
        statement.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void close(final Connection connection) {
    if (connection == null) {
        return;
    }
    try {
        connection.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void close(final ResultSet resultSet) {
    if (resultSet == null) {
        return;
    }
    try {
        resultSet.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

我將使用equals實現為此Table對象創建一個抽象,該抽象將對客戶端隱藏所有詳細信息。 Java是一種面向對象的語言,因此最好將對象用於其存在的目的。

有一個開放源代碼Java框架可以做到這一點:

www.diffkit.org

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM