Я пытаюсь сравнить два набора данных из разных БД через Java.
Источник db:-oracle,sql,другая база данных.
Цель db:Hive
Я установил соединение JDBC с обеими базами данных и получил результат в двух разных наборах результатов.
sourceData
targetData
Теперь я хочу сравнить два набора результатов и указать на различия. Подход, о котором я думаю, состоит в том, чтобы добавить оба набора результатов в хэш-карту и сравнить. Пожалуйста, дайте мне знать, правильный ли мой подход или есть лучший способ сделать то же самое.
Поделитесь ссылками, которые могут мне помочь.
Заранее спасибо.
@RaMPrabU Я хочу сравнить столбец результатов, таблица имеет столбец pk и столбцы без pk. я хочу сравнить его по столбцам. Спасибо
Вы должны правильно реализовать метод equals и методы хэш-кода (согласно вашей логике), и я надеюсь, что мой ответ поможет найти различия.
Реализация на самом деле зависит от ваших требований.
Имеет ли значение порядок строк или столбцов? Нужно ли сравнивать типы данных? и т.п.
Самый простой подход для вас — запустить два запроса с предложением ORDER BY
, одинаковым для обоих запросов. И сравните строки из наборов данных за одну итерацию, например:
ResultSet rs1 = ...;
ResultSet rs2 = ...;
boolean rs1next;
boolean rs2next;
while ((rs1next = rs1.next()) || (rs2next = rs2.next())) {
//do your stuff here
}
Решение аналогично предложенному @Аид, но вместо этого используйте Set
s.
Создайте класс держателя, который содержит все значения, которые вы хотите сравнить, и который переопределяет equals()
и hashCode()
:
class Data {
// the fields you wish to compare
// override hashCode
// override equals
}
Создайте Set<Data> source, target;
(используйте LinkedHashSet
, если важен порядок строк) и добавьте строки от ResultSet sourceData
до source
и то же самое для targetData
.
Затем вы можете использовать простые Set
операции.
Это оставит все элементы в copy
, которые не встречаются в target
:
Set<Data> copy = new LinkedHashSet<>(source);
copy.removeAll(target);
Это сохранит все элементы в copy
, которые делать встречаются в target
:
Set<Data> copy = new LinkedHashSet<>(source);
copy.retainAll(target);
Это создаст объединение всех элементов в copy
и target
:
Set<Data> copy = new LinkedHashSet<>(source);
copy.addAll(target);
Я создал copy
, потому что эти операции изменяют Set
, таким образом (используя копию) ваш Set<Data> source
не изменится.
Вы также можете обернуть все эти вызовы removeAll()
, retainAll()
и addAll()
в if
-оператор, что позволит вам напрямую выполнять определенные действия. Например, с removeAll()
:
if (copy.removeAll(target)) {
// elements were removed from copy which were in target
} else {
// nothing was removed
}
Я помогу вам с самим подходом hashmap. Установленный вами Предполагая содержит уникальные значения. Мой следующий код поможет вам.
Set<Data> soruceData;
Set<Data> targetData;
HashMap<Data,Integer> comparisonMap;
for(Data data:targetData){
comparisonMap.put(data,0);
}
for(Data data:soruceData){
if (targetData.contains(data))
comparisonMap.put(data,1);
else
comparisonMap.put(data,0);
}
Теперь у вас есть хэш-карта, которая говорит о разнице между двумя списками. 1- означает наличие в двух наборах 0- значит не присутствует ни в одном из наборов
ПРИМЕЧАНИЕ, пожалуйста, правильно реализуйте hascode и equals при использовании set и hascode
Почему бы не использовать Boolean
вместо Integer
?
@Lino это тоже хорошо
трудно предложить решение без логики сравнения. Пожалуйста, укажите, как вы хотите сравнить данные. На основе идентификатора или имени или всех полей.