alibaba / tamper

A Java Bean to Java Bean mapper that recursively copies data from one object to another
http://github.com/alibaba/tamper
Apache License 2.0
247 stars 113 forks source link

Introduction

tamper是一款处理bean/map进行属性复制映射的工具,支持递归,集合等深度映射.

Why need tamper

这里列觉了几种需要使用tamper的场景:

Why tamper

目前的插件支持:

Maven repository

<dependency>
   <groupId>com.alibaba.tamper</groupId>
   <artifactId>tamper</artifactId>
   <version>1.0.3</version>
</dependency>

FAQ

1.How to import to eclipse by maven?

  mvn eclipse:eclipse

2.How to build project by maven?

  mvn clean package

3.How to run testcase by maven?

  mvn test

Example1:

自定义映射规则,处理bean/map <-> bean/map

Step 1 (define mapping config)

bean-mappings xmlns="https://github.com/alibaba/tamper/schema/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://github.com/alibaba/tamper/schema/mapping https://raw.github.com/alibaba/tamper/master/src/main/resources/META-INF/mapping.xsd">
        <!--  (bean-bean) mapping 测试 -->
        <bean-mapping batch="true" srcClass="com.agapple.mapping.object.SrcMappingObject" targetClass="com.agapple.mapping.object.TargetMappingObject" reversable="true">
            <field-mapping srcName="intValue" targetName="intValue" />
            <field-mapping targetName="integerValue" script="src.intValue + src.integerValue" /> <!-- 测试script -->
            <field-mapping srcName="start" targetName="start" />
            <field-mapping srcName="name" targetName="targetName" /> <!--  注意不同名 -->
            <field-mapping srcName="mapping" targetName="mapping" mapping="true" />
        </bean-mapping>

        <bean-mapping batch="true" srcClass="com.agapple.mapping.object.NestedSrcMappingObject" targetClass="com.agapple.mapping.object.NestedTargetMappingObject" reversable="true">
            <field-mapping srcName="name" targetName="name" defaultValue="ljh" /> <!-- 测试default value -->
            <field-mapping srcName="bigDecimalValue" targetName="value" targetClass="string" defaultValue="10" /> <!-- 测试不同名+不同类型+default value  -->
        </bean-mapping>

    </bean-mappings>

Step 2 (do mapping)

public BeanMapping srcMapping    = BeanMapping.create(SrcMappingObject.class, TargetMappingObject.class);
public BeanMapping targetMapping = BeanMapping.create(TargetMappingObject.class , SrcMappingObject.class);

    @Test
    public void testBeanToBean_ok() {
        SrcMappingObject srcRef = new SrcMappingObject();
        srcRef.setIntegerValue(1);
        srcRef.setIntValue(1);
        srcRef.setName("ljh");
        srcRef.setStart(true);

        TargetMappingObject targetRef = new TargetMappingObject();// 测试一下mapping到一个Object对象
        srcMapping.mapping(srcRef, targetRef);

        SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次
        targetMapping.mapping(targetRef, newSrcRef);
    }

Example2:

类似于BeanUtils/BeanCopier,根据同名属性进行自动映射,不需要定义任何的mapping.xml

public BeanCopy srcCopy    = BeanCopy.create(SrcMappingObject.class, TargetMappingObject.class);
    public BeanCopy targetCopy = BeanCopy.create(TargetMappingObject.class , SrcMappingObject.class);

    @Test
    public void testBeanToBean_ok() {
        SrcMappingObject srcRef = new SrcMappingObject();
        srcRef.setIntegerValue(1);
        srcRef.setIntValue(1);
        srcRef.setName("ljh");
        srcRef.setStart(true);

        TargetMappingObject targetRef = new TargetMappingObject();// 测试一下mapping到一个Object对象
        srcCopy.copy(srcRef, targetRef);

        SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次
        targetCopy.copy(targetRef, newSrcRef);
    }

Example3:

类似于BeanUtils,处理map<->bean

 public BeanMap beanMap = BeanMap.create(SrcMappingObject.class);

    @Test
    public void testDescribe_Populate_ok() {
        SrcMappingObject srcRef = new SrcMappingObject();
        srcRef.setIntegerValue(1);
        srcRef.setIntValue(1);
        srcRef.setName("ljh");
        srcRef.setStart(true);

        Map map = beanMap.describe(srcRef);

        SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次
        beanMap.populate(newSrcRef, map);
    }

Example4:

Mapping API定义映射

BeanMappingBuilder builder = new BeanMappingBuilder() {

            protected void configure() {
                mapping(HashMap.class, HashMap.class).batch(false).reversable(true).keys("src", "target");
                fields(srcField("one"), targetField("oneOther")).convertor("convertor").defaultValue("ljh");
                fields(srcField("two").clazz(String.class), targetField("twoOther")).script("1+2").convertor(
                                                                                                             StringToCommon.class);
                fields(srcField("three").clazz(ArrayList.class), targetField("threeOther").clazz(HashSet.class)).recursiveMapping(
                                                                                                                                  true);
            }

        };

通过builder可以比较方便的构造mapping config,最后需要生成mapping实例,还需要做一步:

BeanMapping mapping = new BeanMapping(builder);
mapping.mapping(src, dest);//使用

or

BeanMappingConfigHelper.getInstance().register(builder); // 进行注册
BeanMappingObject object = BeanMappingConfigHelper.getInstance().getBeanMappingObject(srcClass,targetClass);
mapping.mapping(src, dest);//使用

问题反馈

  1. qq交流群: 161559791
  2. 邮件交流: jianghang115@gmail.com
  3. 新浪微博: agapple0002
  4. 报告issue:issues