JAVA对象复制-Orika常用方法的简单封装应用

Orika是一种java Bean映射框架,可以实现从一个对象递归拷贝数据至另一个对象。
对象的拷贝在开发中的应用场景非常多,比如我们需要一个新的类只继承原有类的部分属性;亦或者需要一个新的类增加更多的属性(可以用继承实现);亦或者只取两个类中有交集的属性:
在这里插入图片描述

简单封装Orika

由于每次使用都需要new一个MapperFactory的基础类

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

所以我们可以对它进行一个简单的封装:
首先在pom.xml中导入maven依赖,我这里直接找了maven仓库的最新版本

    <dependency>
            <groupId>ma.glasnost.orika</groupId>
            <artifactId>orika-core</artifactId>
            <version>1.5.4</version>
        </dependency>
    </dependencies>

下面是简单封装的MapperUtils工具类,将MapperFactory的初始化方法写在静态代码块中,这样重复调用也只用初始化一次。并且提供了getMapperFactory(),让Orika不局限于工具类中的方法。这里只写了一个类coyp的方法,实际上Orika是很强大的

import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;


public class MapperUtils {
    private static final MapperFacade mapperFacade;
    private static final MapperFactory mapperFactory;

    static {
        mapperFactory = new DefaultMapperFactory.Builder().build();
        mapperFacade = mapperFactory.getMapperFacade();
    }

    /**
     * 将对象sourceObject的值拷贝到对象targetObject中
     */
    public static void copyObject(Object sourceObject, Object targetObject) {
        mapperFacade.map(sourceObject, targetObject);
    }

   //  可以封装更多的常用方法
 
    /**
     * 提供getMapperFactory方便调用其他方法
     */
    public static MapperFactory getMapperFactory() {
        return mapperFactory;
    }
}

调用方法也非常简单,假设已有源对象sourceClass,需要复制一个TargetClass对象,TargetClass可以已有的对象,不一定要new出来。

   TargetClass targetClass = new TargetClass();
   MapperUtils.copyObject(sourceClass,targetClass);
 //MapperUtils.getMapperFactory().getMapperFacade().map(sourceClass,targetClass);

实例测试

这边创建两个测试用的实例类:
SourceClass作为复制源对象;TargetClass作为复制目标对象

public class SourceClass {
    private String aaa;
    private int bbb;
    private String ccc;
    private String eee;
    
	....省略get set方法
}
public class TargetClass{
    private String aaa;
    private String bbb;
    private int ccc;
    private String ddd;
    
	....省略get set方法
}

写一个main方法进行测试
例子中包含了几种特殊情况:①属性名相同,数据类型不同;②源类有,目标类没有的属性;源类没有,目标类有的属性 ③目标类属性已有值
①情况一: 源类中(int类型)bbb=1,ccc=“c”

  public static void main(String[] args) {
        SourceClass sourceClass=new SourceClass();
        sourceClass.setAaa("a");
        sourceClass.setBbb(1);
        sourceClass.setCcc("c");
        TargetClass targetClass=new TargetClass();
        MapperUtils.copyObject(sourceClass,targetClass);
        System.out.println(targetClass);
    }

运行结果是直接报错了:
在这里插入图片描述
这个报错很好理解,就是在复制ccc的时候,由于sourceClass 中ccc是String类型的"c",而TargetClass是int类型,所以String的"c"肯定无法转换成int。
②情况二: 源类中(int类型)bbb=1,ccc=“3”

 public static void main(String[] args) {
        SourceClass sourceClass=new SourceClass();
        sourceClass.setAaa("a");
        sourceClass.setBbb(1);
        sourceClass.setCcc("3");
        sourceClass.setEee("e");
        TargetClass targetClass=new TargetClass();
        MapperUtils.copyObject(sourceClass,targetClass);
        System.out.println(targetClass);
    }

可以看到控制台正常输出了targetClass:

TargetClass{aaa=a, bbb=1, ccc=3, ddd=null}

通过debugger看到,sourceClass中int类型的bbb=1成功转换成了targetClass中的String类型的“1”;String类型的ccc=“3”成功转换成了int类型的3;而eee由于targetClass没有,所以也不存在任何属性与其原有值对应;而targetClass中ddd由于sourceClass没有对应的属性,所以为null。
在这里插入图片描述
③情况三 当目标类已有值,设置targetClass中的ccc=2,ddd=“d”

 public static void main(String[] args) {
        SourceClass sourceClass=new SourceClass();
        sourceClass.setAaa("a");
        sourceClass.setBbb(1);
        sourceClass.setCcc("3");
        sourceClass.setEee("e");
        TargetClass targetClass=new TargetClass();
        targetClass.setCcc(2);
        targetClass.setDdd("d");
        MapperUtils.copyObject(sourceClass,targetClass);
        System.out.println(targetClass);
    }

通过debugger可以看到ccc值被覆盖,ddd的值依旧保留
在这里插入图片描述

结论

从测试结果来看,这个方法能实现的复制:只复制两个类中属性名相同的字段,且当字段名相同类型不同的时要求值能正常转换;相同属性名的值会被源类的值覆盖,目标类的原有属性假如在源类中没有相同属性则会保留原有值。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值