반사

2017-03-23 7 views
0
한다고 가정

우리는 2 DTO들이 있습니다반사

어떻게 단순히 사용하지 않고 예 (사용자 정의 또는 반사 /) 일반적인 코드를 사용하여 이러한 DTO들에 매핑하는
public class ClassA { 
    private String elementAClassA; 
    private String elementBClassA; 
    private Integer elementCClassA; 
} 

public class ClassB { 
    private String elementAClassB; 
    private String elementBClassB; 
    private Integer elementCClassB; 
} 

:

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); 
     mapperFactory.classMap(ClassA.class, ClassB.class) 
       .field("elementAClassA", "elementAClassB") 
       .field("elementBClassA", "elementBClassB") 
       .field("elementCClassA", "elementCClassB").register(); 

답변

0
I found the solution and hope will help others. 
Steps are as below: 

1. Overide newClassMapBuilder of Factory class. 
2. fetch fields of both classes using Field reflection. 
3. map new field to build, if elementName matched. 
4. Then, create factory and pass this overiden class. 

-- Point 1-3 are in below code: 
import java.lang.reflect.Field; 
import ma.glasnost.orika.DefaultFieldMapper; 
import ma.glasnost.orika.MapperFactory; 
import ma.glasnost.orika.metadata.ClassMapBuilder; 
import ma.glasnost.orika.metadata.ClassMapBuilder.Factory; 
import ma.glasnost.orika.metadata.Type; 
import ma.glasnost.orika.property.PropertyResolverStrategy; 

public class PlainElementToStdElementMapper extends Factory { 

    @Override 
    protected <A, B> ClassMapBuilder<A, B> newClassMapBuilder(
      Type<A> aType, Type<B> bType, 
      MapperFactory mapperFactory, 
      PropertyResolverStrategy propertyResolver, 
      DefaultFieldMapper[] defaults) { 
     final ClassMapBuilder<A, B> newBuilder = super.newClassMapBuilder(
       aType, bType, mapperFactory, propertyResolver, defaults); 

     Field[] sourceFields = aType.getRawType().getDeclaredFields(); 
     Field[] destFields = bType.getRawType().getDeclaredFields(); 

     for (int elementA = 0; elementA < sourceFields.length; elementA++) { 
      for (int elementB = 0; elementB < destFields.length; elementB++) { 
       if (sourceFields[elementA].getName().equalsIgnoreCase("Std"+destFields[elementB].getName())) { 
        newBuilder.field(sourceFields[elementA].getName(), destFields[elementB].getName()); 
       } 
      } 
     } 
     return newBuilder; 
    } 
} 


4. Create factory: 

     final MapperFactory factory = new DefaultMapperFactory.Builder(). 
        classMapBuilderFactory(new PlainElementToStdElementMapper()).build(); 

     factory.classMap(ClassA.class, ClassB.class).byDefault().register(); 
       MapperFacade mapperFacade = factory.getMapperFacade(); 
0

한 표현 (ClassA)에서 다른 표현 (ClassB)으로 공통 속성을 매핑하는 방법을 묻는 경우 documentation에 표시된대로 byDefault()을 사용합니다.

유형에 따라 다르거 나 두 표현간에 이름이 다르다는 것은 명확하지 않습니다 (Java로 읽을 수 없음). 리플렉션은 필드의 이름이 동일하고 어떤 경우에 byDefault()을 사용해야하는 경우에만 유용합니다. 또는 동일한 유형이고 각각의 표현에 각 유형 중 하나만 있으면 자동 와이어 형식 매핑을 수행 할 수 있습니다 ; 그러나 당신은 당신이 원하지 않을 모든 종류의 가정을 할 것입니다.

+0

byDefault()는 두 클래스 모두에 대해 fieldName이 동일한 경우에만 사용할 수 있습니다. 유형에 관계없이. btw, 나는 해결책을 발견했다. 공장의 newClassMapBuilder 메소드를 오버라이드 (override)하는 것으로 가능합니다. 곧 해결책을 게시 할 예정입니다. :) – Shyam

+0

나는 그것을 깨닫는다. 그러나 (당신의 업데이트 이전에) 당신이 이름이나 타입을 제공하고 있는지를 말할 수 없었다. – Daedalus