如何收听集合中的变化?

时间:2017-02-07 10:42:49

标签: java spring triggers spring-data dbf

我必须检查由旧的第三方应用程序填充的旧嵌入式DBF数据库中的更改。我无法访问该应用程序的源代码,也无法在数据库中放置触发器或其他任何内容。对于业务约束,我无法改变...

我的目标是使用Java应用程序从该数据库的表(~1500条记录)中捕获新记录,删除记录和修改记录以进行进一步处理。我的Spring应用程序可以通过带有HXTT DBF驱动程序的JPA / Hibernate访问数据库。

我现在正在寻找一种有效捕获数据库中第三方应用程序所做更改的方法。

我是否必须定期阅读整个表格并检查每个记录是否仍未更改或在两个读数中应用任何类型的差异?我可以在我的Java应用程序中设置一种“触发器”吗?如何正确地听取这些变化?

1 个答案:

答案 0 :(得分:1)

当数据发生变化时,没有JPA机制可以从数据库中获取回调。

唯一的选择是建立自己的变更检测。通常,您将首先检测添加,删除哪些实体以及哪些实体仍然存在。对于仍然存在的一次,您将需要检查它们是否已更改,因此实体需要equals()方法。 实体由主键标识,因此您需要获取所有主键的集合,一旦您拥有,您可以轻松使用Guava的Sets方法生成3组添加,删除和存在(之前和现在),像这样。

List<MyEntity> old = new ArrayList<>(); // load from the DB last time
List<MyEntity> current = new ArrayList<>(); // loaded from DB now

Map<Long, MyEntity> oldMap = old.stream().collect(Collectors.toMap(MyEntity::getId, Function.<MyEntity>identity() ));
Map<Long, MyEntity> currentMap = current.stream().collect(Collectors.toMap(MyEntity::getId, Function.<MyEntity>identity()));

Set<Long> oldKeys = oldMap.keySet();
Set<Long> currentKeys = currentMap.keySet();

Sets.SetView<Long> deletedKeys = Sets.difference(oldKeys, currentKeys);
Sets.SetView<Long> addedKeys = Sets.difference(currentKeys, oldKeys);
Sets.SetView<Long> couldBeChanged = Sets.intersection(oldKeys, currentKeys);

for (Long id : couldBeChanged) {
    if (oldMap.get(id).equals(currentMap.get(id))) {
        // entity with this id was changed 
    }
}