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:两个注解不可以同时出现在一个类中
如果有没说明白的地方可以留言
Javers 比较两个类的差异的更多相关文章
- 通过实现System.IComparable接口的CompareTo方法对两个类进行比较
假设现在有一个学生类 class Student { int age; public Student(int age) { this.age = age; } } 要使学生类之间能进行比较,实现Sys ...
- 【java回调】java两个类之间的回调函数传递
背景交代:熟悉用js开发的cordovaAPP:对java一窍不通的我,老师让做一个监测用户拍照事件的功能,无奈没有找到现成的库,无奈自己动手开发java插件~~0基础java GreenHand,祝 ...
- ORACLE如何比较两个数据库的差异
ORACLE怎么比较两个数据库的差异 方法1:使用PL-SQL工具 点击 工具->比较用户对象
- diff 比较两个文件的差异
功能:比较两个文件的差异,并把不同地方的信息显示出来.默认diff格式的信息. diff比较两个文件或文件集合的差异,并记录下来,生成一个diff文件,这也是我们常说的补丁文件.也使用patch命令对 ...
- Reader与InputStream两个类中的read()的区别
InputStream类的read()方法是从流里面取出一个字节,他的函数原型是 int read(); ,Reader类的read()方法则是从流里面取出一个字符(一个char),他的函数原型也是 ...
- 简单看看这两个类 String和StringBuilder
我记得以前在园子里面讨论这两个类的文章有很多很多,并且还拿出了很多的测试报告,在什么情况下,谁比谁快,在什么情况下,该用谁 不该用谁等等这些,我这里就不比较了,我就简单看看他们里面的内部实现,那就先看 ...
- git日志输出格式及两个版本之间差异列表
查看commit id git log --pretty=format:"%h" git log --pretty=format:"%H" 获取两个版本间差异的 ...
- C++学习笔记一 —— 两个类文件互相引用的处理情况
先记录一些零碎的知识点: 1. 一个类可以被声明多次,但只能定义一次,也就是可以 class B; class B; class B; ……; class B {……}; 这样子. 2. 一个 ...
- 使用 Attribute +反射 来对两个类之间动态赋值
看同事使用的 一个ORM 框架 中 有这样一个功能 通过特性(附加属性)的功能来 实现的两个类对象之间动态赋值的 功能 觉得这个功能不错,但是同事使用的 ORM 并不是我使用的 Dapper 所 ...
随机推荐
- 带你自定义实现Spring事件驱动模型
Spring 事件驱动模型概念 Spring 事件驱动模型就是观察者模式很经典的一个应用,我们可以通过Spring 事件驱动模型来完成代码的解耦. 三角色 Spring 事件驱动模型或者说观察者模式需 ...
- RocketMQ 介绍与安装
目录 RocketMQ 介绍 MQ 介绍 MQ 作用 MQ 缺点 MQ 常见产品 RocketMQ 简介 RocketMQ 架构 RocketMQ 安装 RocketMQ 介绍 MQ 介绍 定义: M ...
- Java包装类和处理对象
Java中基本类型变量和字符串之间的转换 public class Primitive2String { public static void main(String args[]) { String ...
- fluem读取文件并写入到hadoop的hdfs
接上一章,本章介绍使用 crontab 像指定文件定时写入,使用fluem 读取并写入到hadoop的hdfs 前提准备已安装好fluem ,和hadoop(推荐单机即可毕竟做实验) 一.进入终端执行 ...
- 【刷题-LeetCode】190 Reverse Bits
Reverse Bits Reverse bits of a given 32 bits unsigned integer. Example 1: Input: 0000001010010100000 ...
- 配置vscode的C++环境Unexpected GDB output from command "-environment-cd
原因 中文字符 换成D盘目录下以后.
- 动态代理jdk的Proxy与spring的CGlib
1. 为什么要使用动态代理? 动态代理:在不改变原有代码的情况下上进行对象功能增强 使用代理对象代替原来的对象完成功能 进而达到拓展功能的目的 2.JDK Proxy 动态代理面向接口的动态代理 特点 ...
- 机器学习-softmax回归 python实现
---恢复内容开始--- Softmax Regression 可以看做是 LR 算法在多分类上的推广,即类标签 y 的取值大于或者等于 2. 假设数据样本集为:$\left \{ \left ( X ...
- 【程序18】求s=a+aa+aaa+aaaa+aa...a的值
求s=a+aa+aaa+aaaa+aa-a的值,其中a是一个数字.例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制. 知识点:在Python 3里,reduce( ...
- Java 基础02
参照:https://www.cnblogs.com/ZXF6/p/11530009.html 类和对象 /** * java 中的类和对象 * * 一.局部变量的作用域. * * 二.面向对象的概述 ...