2 votes

ModelMapper - une manière simple d'aplatir un objet

J'ai un objet source dont la structure est la suivante :

class SourceA {
  int www;
  SourceB sourceB;
}

class SourceB {
  int xxx;
  int yyy;
  int zzz;
}

Et la destination :

class Dest {
  int aaa;
  int bbb;
  int ccc;
  int ddd;
}

C'est la manière la plus directe de configurer le mappage :

ModelMapper mapper = new ModelMapper();

mapper.createTypeMap(SourceA.class, Dest.class)
  .addMapping(SourceA::getWww, Dest::setDdd)
  .addMapping(src -> src.getSourceB().getXxx(), Dest::setAaa)
  .addMapping(src -> src.getSourceB().getYyy(), Dest::setBbb)
  .addMapping(src -> src.getSourceB().getZzz(), Dest::setCcc);

Mais j'aimerais faire quelque chose comme ça :

ModelMapper mapper = new ModelMapper();

mapper.createTypeMap(SourceB.class, Dest.class)
  .addMapping(SourceB::getXxx, Dest::setAaa)
  .addMapping(SourceB::getYyy, Dest::setBbb)
  .addMapping(SourceB::getZzz, Dest::setCcc);

mapper.createTypeMap(SourceA.class, Dest.class)
  .addMapping(SourceA::getWww, Dest::setDdd)
  .addMapping(SourceA::getSourceB, ???); // How to reference self here?

Et toujours convertir SourceA en Dest en une seule étape, comme dans la première option :

Dest dest = mapper.map(sourceA, Dest.class);

Il s'agit évidemment d'un exemple simplifié à l'extrême, mais mon problème est de créer un mappage où, à un moment donné, je peux faire référence à un autre mappage pour l'objet Root dest.

2voto

Butiri Dan Points 1704
  1. Mappage explicite

    • Convertir la classe imbriquée et créer l'objet de destination partiellement mappé
    • Mappage des valeurs restantes sur l'objet de destination précédent

    public static void main(String[] args) { ModelMapper createTypeMap = new ModelMapper(); SourceA sourceA = new SourceA(); SourceB sourceB = new SourceB();

    sourceB.setXxx(1);
    sourceB.setYyy(2);
    sourceB.setZzz(3);
    sourceA.setWww(4);
    sourceA.setSourceB(sourceB);
    
    Dest dest = createTypeMap.createTypeMap(SourceB.class, Dest.class)
            .addMapping(SourceB::getXxx, Dest::setAaa)
            .addMapping(SourceB::getYyy, Dest::setBbb)
            .addMapping(SourceB::getZzz, Dest::setCcc)
            .map(sourceB);
    
    createTypeMap.createTypeMap(SourceA.class, Dest.class)
            .addMapping(SourceA::getWww, Dest::setDdd)
            .map(sourceA, dest);
    
    System.out.println(dest);

    }

  2. Implicit mapping, vous pouvez utiliser l'une des solutions de contournement suivantes

    • Ajouter un setter à l'objet de destination pour qu'il corresponde aux champs de la source

    class Dest {

    int xxx;
    int bbb;
    int ccc;
    int ddd;
    
    public void setWWW(final int xxx) {
        this.xxx = xxx;
    }
    
    public void setXXX(final int aaa) {
        this.aaa = aaa;
    }
    
    public void setYYY(final int bbb) {
        this.bbb = bbb;
    }
    
    public void setZZZ(final int ccc) {
        this.ccc = ccc;
    }

    }

  • Ou modifier les noms des champs de destination ou de source pour qu'ils correspondent l'un à l'autre.

utiliser la configuration et le mappage suivants

ModelMapper modelMapper = new ModelMapper();

modelMapper.getConfiguration()
            .setMatchingStrategy(MatchingStrategies.LOOSE);

dest = modelMapper.map(sourceA, Dest.class);

System.out.println(dest);

Sortie

Dest{aaa=1, bbb=2, ccc=3, ddd=4}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X