2

次の例のように、アプリケーションに(ドメインオブジェクトからDTOへ、およびその逆の)詳細なプロパティマッピングがあります。

...

<field>
    <a>employee.id</a>
    <b>employeeId</a>
</field>

...

DozerがドメインをDTOに変換すると、にマップemployee.idされます。これで問題ありませんemployeeId
DozerがDTOをドメインに変換するemployeeIdと、id=employeeIdを持つ新しいEmployeeインスタンスにマップされます。

この深いプロパティマッピングのロジックを作成したいのですが、解決策がわかりません。実装CustomConverter(または拡張DozerConverter)しようとしましたが、Dozerはソースクラスと宛先クラスとして整数型を渡します(結果として整数を期待します)。

編集:より正確に言えば、私が必要としているのはemployee、ドメインでDTOが0の null場合にマップすることです。employeeId

これは可能ですか?

何かアドバイス?

回答に応じて編集:フィールドレベルのカスタムコンバーターの問題を解決します。前述のマッピングの代わりに、今私はこのようなものを持っています...

...

<field custom-converter="ManyToOneIdMapper" custom-converter-param="id">
    <a>employee</a>
    <b>employeeId</b>
</field>

...

ManyToOneIdMapperで私は持っています...

public class ManyToOneIdMapper implements ConfigurableCustomConverter{

//...
//parameter field declaration, setParameter and getParameter implementations etc.
//...

public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, 
        Class<?> destinationClass, Class<?> sourceClass) {
    try {

        if(sourceClass.equals(Integer.class)){
            Integer src=(Integer)sourceFieldValue;

            if(src==null || src==0)
                return null;

            String setterName=formatMethodName("set", getParameter());
            Method setterMethod=destinationClass.getMethod(setterName, Integer.class);
            Object instance=destinationClass.newInstance();

            setterMethod.invoke(instance, src);

            return instance;
        }else{    
            if(sourceFieldValue==null)
                return 0;

            String getterName=formatMethodName("get", getParameter());
            Method getterMethod=sourceClass.getMethod(getterName);
            Object instance=getterMethod.invoke(sourceFieldValue);

            return instance;
        }
    } catch (Exception e){}
    return null;
}

/**
 * @return - method name (most often setter or getter)  according to fieldName.
 * For example formatMethodName("get", "id") returns "getId"
 */
protected String formatMethodName(String methodPrefix, String fieldName){
    String trimmedFieldName=fieldName.trim();
    String firstLetter=String.valueOf(trimmedFieldName.charAt(0));
    String capitalizedFirstLetter=firstLetter.toUpperCase();
    String methodName=methodPrefix+""+capitalizedFirstLetter+""+fieldName.substring(1);

    return methodName;
}

custom-converter-paramドメインオブジェクトのidフィールドの名前です。その名前で、コンバーターでsetterメソッドまたはgetterメソッドを呼び出すだけです。おそらく、それは最も幸せな解決策ではありませんが、私の問題のシナリオでは機能します。

4

3 に答える 3

1

IDが0の場合は、CustomConverter(他の回答ごとに)を使用するかDozerEventListener、マッピングの終了後にaを使用して従業員オブジェクトをnullに戻すことができます。

于 2011-06-16T13:02:23.043 に答える
0

ModelMapper(作成者はこちら)をチェックしてください。構成やカスタムコンバーターを必要とせずに、説明したシナリオをインテリジェントにマッピングします。モデルを検討する:

class Person {
  Employee employee;
}

class Employee {
  int id;
}

class PersonDTO {
  int employeeId;
}

マッピングは簡単です:

ModelMapper modelMapper = new ModelMapper();
PersonDTO personDTO = modelMapper.map(person, PersonDTO.class);

Person.employeeがゼロでない場合に条件付きでマッピングするにPersonDTO.employeeIdは、条件を作成し、Person.employeeのプロパティマッピングを次の条件で追加します。

Condition<?, ?> empIdIsNotZero = new Condition<PersonDTO, Employee>() {
  public boolean applies(MappingContext<PersonDTO, Employee> context) {
    return context.getSource().getEmployeeId() != 0;
  }
};

modelMapper.addMappings(new PropertyMap<PersonDTO, Person>() {
  protected void configure() {
    when(empIdIsNotZero).map(source).setEmployee(null);
  }
});

empIdIsNotZero条件が適用されると、マッピングは通常どおりに行われます。それ以外の場合、マッピングはスキップPerson.employeeされ、nullに設定されます。

その他のドキュメントと例については、ModelMapperサイトを確認してください。

http://modelmapper.org

于 2011-06-23T19:17:47.470 に答える
0

CustomConverterたとえば、親オブジェクトをマップする必要があります。

ドメイン

class PersonA {
    ...
    int employeeId;
    ...
}

DTO

class PersonB {
    ...
    Employee employee;
    ...
}

class Employee {
    ...
    int id;
    ...
}

2つのクラスをマップし、PersonAPersonB使用してCustomConverter、これにより、任意の方法でそれらを構築できます。

于 2011-06-16T12:30:15.173 に答える