GithubHelp home page GithubHelp logo

fast-object-diff's Introduction

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比较,具体使用参考测试用例 maven**仓库引用:
<dependency>
  <groupId>com.github.colincatsu</groupId>
  <artifactId>fast-object-diff</artifactId>
  <version>1.6</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);
    }

}

fast-object-diff's People

Contributors

charles94jp avatar colincatsu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fast-object-diff's Issues

无法支持Boolean类型字段

java.lang.IllegalArgumentException: Attempt to get java.lang.Boolean field "com.xxxxx.vo.EntrySettingVo.consumptionLimit" with illegal data type conversion to boolean
	at sun.reflect.UnsafeFieldAccessorImpl.newGetIllegalArgumentException(UnsafeFieldAccessorImpl.java:69)
	at sun.reflect.UnsafeFieldAccessorImpl.newGetBooleanIllegalArgumentException(UnsafeFieldAccessorImpl.java:116)
	at sun.reflect.UnsafeObjectFieldAccessorImpl.getBoolean(UnsafeObjectFieldAccessorImpl.java:41)
	at java.lang.reflect.Field.getBoolean(Field.java:428)
	at com.fastobject.diff.AbstractObjectDiff.generateOneDiffs(AbstractObjectDiff.java:213)
	at com.fastobject.diff.AbstractObjectDiff.generateDiff(AbstractObjectDiff.java:138)
	at com.fastobject.diff.AbstractObjectDiff.generateDiff(AbstractObjectDiff.java:28)
	at com.fastobject.diff.AbstractObjectDiff.genChineseDiffStr(AbstractObjectDiff.java:23)

自定义类和枚举类无法对比到么?

调试了一遍,自定义类型和枚举类返回的DiffWapper是null

搜索了很多fast-object-diff的例子,都是基本类型加一个List<自定义类>

public class User {
    @DiffLog(name = "name")
    private String name;

    @DiffLog(name = "students")
    private List<Student> students;
}

我遇到的问题是:如果抛开List,直接是一个自定义类型(或者枚举),就无法比对到这个字段了

public class User {
    @DiffLog(name = "name")
    private String name;

    @DiffLog(name = "students")
    private Student student;
}

请问是功能不支持么? 有这个需求应该怎么办?

不支持java8 LocalDataTime 格式字段

bean class:

@Getter
@Setter
public class DiffTest {

    private String id;

//    @DiffLog(name = "消费限制")
//    private Boolean consumptionLimit;

    @DiffLog(name = "消费额")
    private BigDecimal total;

    @DiffLog(name = "时间")
    private LocalDateTime time;
}

test code:

@Test
public void test() throws Exception {
    DiffTest o1 = new DiffTest();
    o1.setId("1");
    o1.setTotal(new BigDecimal("123"));
    o1.setTime(LocalDateTime.now());

    DiffTest o2 = new DiffTest();
    o2.setId("1");
    o2.setTotal(new BigDecimal("1234"));
    o2.setTime(LocalDateTime.now().plusHours(1L));

    String chineseDiffStr = ChineseObjectDiff.genChineseDiffStr(o1, o2);
    System.out.println(chineseDiffStr);
}

println out :
「消费额」由[123]修改为[1234]

简单对象list不能对比

    demo1 demo1 = new demo1();
    demo1.setName("name1");
    demo1.setDesc("desc1");
    demo1.setValue(1);
    demo1.setList(Lists.newArrayList(1l,2l));

    demo1 demo2 = new demo1();
    demo2.setName("name2");
    demo2.setDesc("desc2");
    demo2.setValue(2);
    demo2.setList(Lists.newArrayList(2l,3l));

    List<DiffWapper> diffWappers = AbstractObjectDiff.generateDiff(demo1, demo2);
    System.out.println(JsonUtils.encode(diffWappers));

    System.out.println("==========");

    String s = ChineseObjectDiff.genChineseDiffStr(demo1, demo2);

    System.out.println(s);


@DiffLog(name = "名称")
private String name;

@DiffLog(name = "描述")
private String desc;

@DiffLog(name = "值")
private Integer value;

@DiffLog(name = "list")
private List<Long> list;

不支持简单类型List集合吗??

@DiffLog(name = "学生id集合")
private List studentIdlist;

你好,使用了Fast-object-diff ,发现 简单类型的List集合 无法处理,这个能支持一下吗??

比较时希望可以添加一个配置,而不依赖于注解去比较

很不错的一款工具!

背景

现在大部分采用的是RPC等微服务架构,不可避免的需要引入别的项目的模型依赖,如果对该模型依赖的对象进行变更,又因为依赖无法添加注解,因此如果加上以下的一些特性,那就更好了!

粗略的方案

不仅仅支持注解方式选择比较的字段以及注解方式的确定list的keyId
可以考虑传入一个配置,由配置确认需要比较的字段以及list的keyid
嵌套对象的话,可以使用field.subfield这样的确认
如:
student.name作为需要比较的字段或者list的keyid

复杂的list嵌套问题

👍 不错的功能。测试一个对象包含list集合,可以正常使用。
我的工作场景中,存在二级的list嵌套:一个对象,存在List 集合,对象A中又存在一层List
请问支持二级嵌套list吗?我自测不通过

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.