Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

colincatsu/fast-object-diff

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

35 Commits

Repository files navigation

Fast-object-diff

我们经常要打一些日志记录,然而手动记录是比价困难的, 也是不方便的,非常需要一个对比java相同对象内不同值的方法 Fast-object-diff就这样诞生.

  1. 支持基本对象 和 Collection集合
  2. 日期可按照自定义格式输出
  3. 注解方法输出日志,配置简单
  4. 忽略不需要的值
  5. 提供基础方法 generateDiff 和扩展方法
  6. 集合中可根据某个key进行对应diff记录,方便乱序中使用diff对比某个Object
  7. 增加Byte和Short类型判断
  8. 增加自定义类型比较,具体使用参考测试用例
  9. 增加java8 LocalDataTime比较,具体使用参考测试用例
  10. 现在大部分采用的是RPC等微服务架构,增加基于配置的方法比较 ,不依赖注解,同时兼容注解和配置

maven中央仓库引用:

<dependency>
 <groupId>com.github.colincatsu</groupId>
 <artifactId>fast-object-diff</artifactId>
 <version>1.7</version>
</dependency>

使用方法很简单:

 public class BeanA {
 
 //使用注解标记列
 @DiffLog(name = "测试a")
 private String a;
 
 //忽略这个
 @DiffLog(name = "测试b", ignore = true)
 private String b;
 
 //集合递归支持
 @DiffLog(name = "BList集合")
 private List<BeanB> bList;
 
 //日期格式转换
 @DiffLog(name = "开始时间",dateFormat = "yyyy-dd-MM hh:mm:ss")
 private Date start;
 
 @DiffLog(name = "价格")
 private BigDecimal price;
 }
 public class BeanB {
 @DiffLogKey(name = "订单编号")//标记集合中对应的key,根据这个key来比对输出
 @DiffLog(name = "主键")
 private Long id ;
 @DiffLog(name = "机场")
 private String name;
 }
 BeanB a1b = new BeanB(1L,"北京");
 BeanB a1b3 = new BeanB(3L,"3");
 BeanB a1b2 = new BeanB(2L,"1");
 
 ArrayList<BeanB> list = new ArrayList<>();
 list.add(a1b);
 list.add(a1b3);
 list.add(a1b2);
 BeanA a1 = new BeanA("1","1",list);
 a1.setStart(new Date());
 // a1.setPrice(new BigDecimal("10.23"));
 
 
 BeanB a2b = new BeanB(1L,"上海");
 BeanB a2b2 = new BeanB(2L,"2");
 
 ArrayList<BeanB> list2 = new ArrayList<>();
 list2.add(a2b);
 list2.add(a2b2);
 final BeanA a2 = new BeanA("2","2",list2);
 a2.setPrice(new BigDecimal("50.852236"));
 List<DiffWapper> diffWappers = AbstractObjectDiff.generateDiff(a1, a2);

结果Json格式:

[
 {
 "diffValue":{
 "newValue":"2",
 "oldValue":"1"
 },
 "logName":"测试a",
 "op":"CHANGE",
 "path":"/a"
 },
 {
 "diffValue":{
 "newValue":"上海",
 "oldValue":"北京"
 },
 "logName":"BList集合.订单编号[1].机场",
 "op":"CHANGE",
 "path":"/bList/1/name"
 },
 {
 "diffValue":{
 "newValue":"2",
 "oldValue":"1"
 },
 "logName":"BList集合.订单编号[2].机场",
 "op":"CHANGE",
 "path":"/bList/2/name"
 },
 {
 "diffValue":{
 "newValue":null,
 "oldValue":"[主键]=3 ,[机场]=3 "
 },
 "logName":"BList集合.订单编号[3]",
 "op":"REMOVE",
 "path":"/bList/3"
 },
 {
 "diffValue":{
 "newValue":null,
 "oldValue":"2019-09-09 02:16:30"
 },
 "logName":"开始时间",
 "op":"REMOVE",
 "path":"/start"
 },
 {
 "diffValue":{
 "newValue":50.852236,
 "oldValue":null
 },
 "logName":"价格",
 "op":"ADD",
 "path":"/price"
 }
]

也可以直接输出中文日志格式:

 String s = ChineseObjectDiff.genChineseDiffStr(a1, a2);

结果直接输出:

测试a[1]修改为[2]
「BList集合.订单编号[1].机场[北京]修改为[上海]
「BList集合.订单编号[2].机场[1]修改为[2]
「BList集合.订单编号[3]」[[主键]=3 ,[机场]=3 ]被删除开始时间[2019-09-09 02:01:54]被删除价格被添加成[50.852236]

也可以使用AbstractObjectDiff+DiffWapper扩展自己的格式输出.

public class ChineseObjectDiff extends AbstractObjectDiff {
 @Override
 protected String genDiffStr(Object sourceObject, Object targetObject) throws Exception {
 List<DiffWapper> diffWappers = generateDiff(sourceObject, targetObject);
 return DiffUtils.genDiffStr(diffWappers);
 }
}

配置使用yaml进行配置,配置classes以及对应的fields即可,如下:

classes:
 - className: com.fastobject.diff.model.BeanF
 fields:
 - name: a
 fullName: 测试a
 ignore: false
 - name: b
 fullName: 测试b
 ignore: true
 - name: bList
 fullName: BList集合
 - name: start
 fullName: 开始时间
 dateFormat : "yyyy-MM-dd hh:mm:ss"
 - name: price
 fullName: 价格
 - className: com.fastobject.diff.model.BeanG
 fields:
 - name: id
 fullName: 主键
 ignore: false
 diffLogKey:
 name: 订单编号
 - name: name
 fullName: 机场
 ignore: false
 - name : startDate
 fullName : 开始时间
 dateFormat : "yyyy-MM-dd hh:mm:ss"
 - name: price
 fullName: 订单金额
 ignore: true
 - name: consumptionLimit
 fullName: 消费限制

使用方法和注解类似,参考单元测试 YamlConfigDiffTest.java 进行使用即可

 DiffConfig diffConfig = ConfigReader.readConfig("diff-config.yaml");
 List<DiffWapper> diffWappers = AbstractObjectDiff.generateDiff(diffConfig,a1, a2);
 String s = ChineseObjectDiff.genChineseDiffStr(diffConfig,a1, a2);

About

java object diff

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

Languages

AltStyle によって変換されたページ (->オリジナル) /