[英]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 | 我有個兄弟
預期輸出應為
這對我有用,請隨時添加鹽調味:
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.