2017-02-07 34 views
0

我必須檢查由舊的第三方應用程序填充的舊嵌入式DBF數據庫中的更改。我無法訪問該應用程序的源代碼,也無法將觸發器或其他任何內容放入數據庫。對於企業的約束,我不能改變......如何聆聽藏品中的變化?

我的目標是從與進一步處理的Java應用程序的數據庫表(〜1500個記錄)捕捉新的記錄,刪除記錄和修改的記錄。我的Spring應用程序可以通過JPA/Hibernate和HXTT DBF驅動程序訪問數據庫。

我正在尋找一種方法來有效捕獲數據庫中第三方應用程序所做的更改。

我一定要定期讀取整個表,檢查每個記錄仍然是不變的,或者兩個讀數內申請任何種類的差異呢?是否有一種「我可以在我的Java應用程序中設置的」觸發器「?如何正確聽取這些變化?

回答

1

當數據發生變化時,沒有從數據庫獲取回調的JPA機制。

唯一的選擇是建立你自己的變化檢測。通常,您會首先檢測添加,刪除哪些實體以及哪些實體仍然存在。對於一旦仍然存在,您將需要檢查它們是否被更改,因此實體需要使用equals()方法。 實體是由它的主鍵確定,所以你需要得到集中的所有主鍵,一旦你有,你可以很容易地使用番石榴的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 
    } 
}