java中Javers 比較兩個類的差異
Javers
在開發過程中遇到需求,比較數據庫中的原數據與新修改要寫入庫中的數據。這個實體類是比較復雜的。例如有基本類型,BigDecimal類型,自定義類型,Date類型,List集合,Set集合,Map集合等。在比較復雜的類的情況下,使用Objects的equals是不適用的。所以為瞭解決這個問題,可以使用Javers庫中的compare方法來解決該問題
引入
<!-- https://mvnrepository.com/artifact/org.javers/javers-core --> <dependency> <groupId>org.javers</groupId> <artifactId>javers-core</artifactId> <version>6.6.2</version> </dependency>
方法:
Javers javers = JaversBuilder.javers().build(); Diff diff = javers.compare(oldObject,newObject) boolean flag = diff.hasChange(); //diff會在控制臺打印出兩個類之間的異同,相同不打印數據,不同會展示出修改前後的數據 //diff.hasChange(); 如果兩個類完全相同,返回值為flase,兩個類不同,返回值為true
示例
public static void main(String[] args) { Javers build = JaversBuilder.javers().build(); //A系統的類 //數據庫中的數據 PromotionDetail promotionDetail = new PromotionDetail(); promotionDetail.setCanEditFlag(true); promotionDetail.setAllGoodsCountType(1); promotionDetail.setName("name1"); PromotionGoods promotionGoods = new PromotionGoods(); promotionGoods.setCount(1); promotionGoods.setDeptName("deptname1"); PromotionGoods promotionGoods1 = new PromotionGoods(); promotionGoods1.setCount(2); promotionGoods1.setDeptName("deptname2"); List<PromotionGoods> list = new ArrayList<>(); list.add(promotionGoods); list.add(promotionGoods1); promotionDetail.setGoods(list); //新數據 PromotionDetail promotionDetail1 = new PromotionDetail(); promotionDetail1.setCanEditFlag(true); promotionDetail1.setAllGoodsCountType(1); promotionDetail1.setName("name2"); PromotionGoods promotionGoods2 = new PromotionGoods(); promotionGoods2.setCount(5); promotionGoods2.setDeptName("deptname3"); PromotionGoods promotionGoods3 = new PromotionGoods(); promotionGoods3.setCount(4); promotionGoods3.setDeptName("deptname3"); List<PromotionGoods> list0 = new ArrayList<>(); list0.add(promotionGoods2); list0.add(promotionGoods3); promotionDetail1.setGoods(list0); Diff compare = build.compare(promotionDetail, promotionDetail1); boolean b = compare.hasChanges(); System.out.println(compare); System.out.println(b); }
//控制臺輸出
Diff:
* changes on com.ef.admin.data.controller.promotion.np.param.PromotionDetail/ :
– 'goods/0.count' changed: '1' -> '5'
– 'goods/0.deptName' changed: 'deptname1' -> 'deptname3'
– 'goods/1.count' changed: '2' -> '4'
– 'goods/1.deptName' changed: 'deptname2' -> 'deptname3'
– 'name' changed: 'name1' -> 'name2'
true ====》為true說明有改變
遇到的問題:
BigDecimal
在比較BigDecimal類型的不同數據時,會出現問題。由於javer.compare()底層是使用的objects的equals方法來判斷兩個數據是否相等,而BigDecimal類型比較時使用equals方法比較存在問題,應該使用BigDecimal類中的compareTo方法比較,詳見https://blog.csdn.net/molihuaya/article/details/79139418
BigDecimalComparatorWithFixedEquals類實現瞭CustomValueComparator<>接口並重寫equals方法
public class BigDecimalComparatorWithFixedEquals implements CustomValueComparator<BigDecimal> { @Override public boolean equals(BigDecimal a, BigDecimal b) { return a.compareTo(b) == 0; }
所以創建javers對象時:
Javers javers = JaversBuilder.javers().registerValue(BigDecimal.class,new BigDecimalComparatorWithFixedEquals()).build();
Date
在比較Date類型的不同數據時,會出現問題。假設在數據中查出的日期類型為Date,新修改的數據為TimeStamp類型。此時使用javers.compare()比較時即使時間點相同,比較出來仍有問題。
數據庫中的數據 2022-02-25 23:59:59.0
新修改的數據 Fri Feb 25 23:59:59 CST 2022
可以通過實現CustomValueComparator<>接口來重寫equals方法
public class EfDateComparator implements CustomValueComparator<Date> { @Override public boolean equals(Date a, Date b) { return a.getTime() == b.getTime(); }
所以創建javers對象時:
Javers javers = JaversBuilder.javers().registerValue(BigDecimal.class,new BigDecimalComparatorWithFixedEquals()).build(); Javers javers = JaversBuilder.javers() .registerValue(BigDecimal.class,new BigDecimalComparatorWithFixedEquals()) .registerValue(BigDecimal.class,new BigDecimalComparatorWithFixedEquals()) .build();
相關註解
在比較兩個類時,可能需要隻比較部分字段或不比較部分字段,可以考慮使用以下兩個註解
//在一個類中,在字段上添加該註解,該類中隻比較有註解的字段 @DiffInclude //在一個類中,在字段上添加該註解,該類中忽略比較有註解的字段 @DiffIgnore //PS:兩個註解不可以同時出現在一個類中
到此這篇關於java中Javers 比較兩個類的差異的文章就介紹到這瞭,更多相關Javers 比較兩個類的差異內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- java如何自定義List中的sort()排序,用於日期排序
- Java Comparator.comparing比較導致空指針異常的解決
- 深入淺出講解Java比較器及數學常用類
- Python進行區間取值案例講解
- 使用python 進行區間取值的方法