Guide pour JMapper

1. Vue d’ensemble

Dans ce didacticiel, nous explorerons JMapper - ** un cadre de cartographie rapide et facile à utiliser.

Nous discuterons de différentes manières de configurer JMapper, d’effectuer des conversions personnalisées, ainsi que du mappage relationnel.

2. Configuration Maven

Premièrement, nous devons ajouter la dépendance JMapper à notre pom.xml :

<dependency>
    <groupId>com.googlecode.jmapper-framework</groupId>
    <artifactId>jmapper-core</artifactId>
    <version>1.6.0.1</version>
</dependency>

3. Modèles source et destination

Avant de commencer la configuration, jetons un coup d’œil sur les simples haricots que nous allons utiliser tout au long de ce tutoriel.

Premièrement, voici notre haricot source - un utilisateur de base:

public class User {
    private long id;
    private String email;
    private LocalDate birthDate;
}

Et notre haricot de destination, UserDto:

public class UserDto {
    private long id;
    private String username;
}
  • Nous utiliserons la bibliothèque pour mapper les attributs de notre bean source User vers notre bean de destination UserDto . **

Il existe trois façons de configurer JMapper: à l’aide de l’API, des annotations et de la configuration XML.

Dans les sections suivantes, nous allons passer en revue chacune d’elles.

4. Utiliser l’API

Voyons comment configurer JMapper à l’aide de l’API.

Ici, nous n’avons besoin d’ajouter aucune configuration à nos classes source et destination. Au lieu de cela, toute la configuration peut être effectuée à l’aide de JMapperAPI , , ce qui en fait la méthode de configuration la plus flexible:

@Test
public void givenUser__whenUseApi__thenConverted(){
    JMapperAPI jmapperApi = new JMapperAPI()
      .add(mappedClass(UserDto.class)
        .add(attribute("id").value("id"))
        .add(attribute("username").value("email")));

    JMapper<UserDto, User> userMapper = new JMapper<>
      (UserDto.class, User.class, jmapperApi);
    User user = new User(1L,"[email protected]", LocalDate.of(1980,8,20));
    UserDto result = userMapper.getDestination(user);

    assertEquals(user.getId(), result.getId());
    assertEquals(user.getEmail(), result.getUsername());
}

Ici, nous utilisons la méthode mappedClass () pour définir notre classe mappée UserDto. Nous avons ensuite utilisé la méthode attribute () pour définir chaque attribut et sa valeur mappée.

Ensuite, nous avons créé un objet JMapper basé sur la configuration et utilisé sa méthode getDestination () pour obtenir le résultat UserDto .

5. Utiliser des annotations

Voyons comment nous pouvons utiliser l’annotation @ JMap pour configurer notre mapping :

public class UserDto {
    @JMap
    private long id;

    @JMap("email")
    private String username;
}

Et voici comment nous allons utiliser notre JMapper :

@Test
public void givenUser__whenUseAnnotation__thenConverted(){
    JMapper<UserDto, User> userMapper = new JMapper<>(UserDto.class, User.class);
    User user = new User(1L,"[email protected]", LocalDate.of(1980,8,20));
    UserDto result = userMapper.getDestination(user);

    assertEquals(user.getId(), result.getId());
    assertEquals(user.getEmail(), result.getUsername());
}

Notez que pour l’attribut id , nous n’avons pas besoin de fournir un nom de champ cible car il s’agit du même nom que le bean source, alors que pour le champ username , il est mentionné qu’il correspond au champ email de la classe User .

Ensuite, nous avons seulement besoin de transmettre les beans source et de destination à notre JMapper - aucune autre configuration n’est nécessaire.

Globalement, cette méthode est pratique car elle utilise le moins de code possible.

6. Utilisation de la configuration XML

Nous pouvons également utiliser la configuration XML pour définir notre mappage.

Voici notre exemple de configuration XML à l’adresse user jmapper.xml__:

<jmapper>
  <class name="com.baeldung.jmapper.UserDto">
    <attribute name="id">
      <value name="id"/>
    </attribute>
    <attribute name="username">
      <value name="email"/>
    </attribute>
  </class>
</jmapper>

Et nous devons passer notre configuration XML à JMapper :

@Test
public void givenUser__whenUseXml__thenConverted(){
    JMapper<UserDto, User> userMapper = new JMapper<>
      (UserDto.class, User.class,"user__jmapper.xml");
    User user = new User(1L,"[email protected]", LocalDate.of(1980,8,20));
    UserDto result = userMapper.getDestination(user);

    assertEquals(user.getId(), result.getId());
    assertEquals(user.getEmail(), result.getUsername());
}

Nous pouvons également passer la configuration XML en tant que Chaîne directement à JMapper au lieu d’un nom de fichier.

7. Cartographie globale

  • Nous pouvons tirer parti du mappage global si nous avons plusieurs champs portant le même nom dans les beans source et cible. **

Par exemple, si nous avons un UserDto1 qui a deux champs, id et email :

public class UserDto1 {
    private long id;
    private String email;

   //standard constructor, getters, setters
}

Le mappage global sera plus facile à utiliser car ils sont mappés sur des champs portant le même nom sur le bean source User .

7.1. Utiliser l’API

Pour la configuration de JMapperAPI , nous utiliserons global () :

@Test
public void givenUser__whenUseApiGlobal__thenConverted() {
    JMapperAPI jmapperApi = new JMapperAPI()
      .add(mappedClass(UserDto.class).add(global())) ;
    JMapper<UserDto1, User> userMapper1 = new JMapper<>
      (UserDto1.class, User.class,jmapperApi);
    User user = new User(1L,"[email protected]", LocalDate.of(1980,8,20));
    UserDto1 result = userMapper1.getDestination(user);

    assertEquals(user.getId(), result.getId());
    assertEquals(user.getEmail(), result.getEmail());
}

7.2. Utiliser des annotations

Pour la configuration des annotations, nous utiliserons @ JGlobalMap au niveau de la classe:

@JGlobalMap
public class UserDto1 {
    private long id;
    private String email;
}

Et voici un test simple:

@Test
public void whenUseGlobalMapAnnotation__thenConverted(){
    JMapper<UserDto1, User> userMapper= new JMapper<>(
      UserDto1.class, User.class);
    User user = new User(
      1L,"[email protected]", LocalDate.of(1980,8,20));
    UserDto1 result = userMapper.getDestination(user);

    assertEquals(user.getId(), result.getId());
    assertEquals(user.getEmail(), result.getEmail());
}

7.3. Configuration XML

Et pour la configuration XML, nous avons l’élément <global/> :

<jmapper>
  <class name="com.baeldung.jmapper.UserDto1">
    <global/>
  </class>
</jmapper>

Et puis passez le nom du fichier XML:

@Test
public void givenUser__whenUseXmlGlobal__thenConverted(){
    JMapper<UserDto1, User> userMapper = new JMapper<>
      (UserDto1.class, User.class,"user__jmapper1.xml");
    User user = new User(1L,"[email protected]", LocalDate.of(1980,8,20));
    UserDto1 result = userMapper.getDestination(user);

    assertEquals(user.getId(), result.getId());
    assertEquals(user.getEmail(), result.getEmail());
}

8. Conversions personnalisées

Voyons maintenant comment appliquer une conversion personnalisée à l’aide de JMapper .

Nous avons un nouveau champ age dans notre UserDto que nous devons calculer à partir de l’attribut User birthDate :

public class UserDto {
    @JMap
    private long id;

    @JMap("email")
    private String username;

    @JMap("birthDate")
    private int age;

    @JMapConversion(from={"birthDate"}, to={"age"})
    public int conversion(LocalDate birthDate){
        return Period.between(birthDate, LocalDate.now())
          .getYears();
    }
}

Ainsi, nous avons utilisé @ JMapConversion pour appliquer une conversion complexe de la date de naissance de l’utilisateur à l’attribut UserDto age . Par conséquent, le champ age sera calculé lorsque nous mapperons User à UserDto :

@Test
public void whenUseAnnotationExplicitConversion__thenConverted(){
    JMapper<UserDto, User> userMapper = new JMapper<>(
      UserDto.class, User.class);
    User user = new User(
      1L,"[email protected]", LocalDate.of(1980,8,20));
    UserDto result = userMapper.getDestination(user);

    assertEquals(user.getId(), result.getId());
    assertEquals(user.getEmail(), result.getUsername());
    assertTrue(result.getAge() > 0);
}

9. Cartographie relationnelle

Enfin, nous discuterons du mapping relationnel. Avec cette méthode, nous devons définir notre JMapper en utilisant à chaque fois une classe cible.

Si nous connaissons déjà les classes cibles, nous pouvons les définir pour chaque champ mappé et utiliser RelationalJMapper .

Dans cet exemple, nous avons un bean source User :

public class User {
    private long id;
    private String email;
}

Et deux beans de destination UserDto1 :

public class UserDto1 {
    private long id;
    private String username;
}

Et UserDto2 :

public class UserDto2 {
    private long id;
    private String email;
}

Voyons comment tirer parti de notre RelationalJMapper.

9.1. Utiliser l’API

Pour notre configuration d’API, nous pouvons définir des classes cibles pour chaque attribut à l’aide de targetClasses () :

@Test
public void givenUser__whenUseApi__thenConverted(){
    JMapperAPI jmapperApi = new JMapperAPI()
      .add(mappedClass(User.class)
      .add(attribute("id")
        .value("id")
        .targetClasses(UserDto1.class,UserDto2.class))
      .add(attribute("email")
        .targetAttributes("username","email")
        .targetClasses(UserDto1.class,UserDto2.class)));

    RelationalJMapper<User> relationalMapper = new RelationalJMapper<>
      (User.class,jmapperApi);
    User user = new User(1L,"[email protected]");
    UserDto1 result1 = relationalMapper
      .oneToMany(UserDto1.class, user);
    UserDto2 result2 = relationalMapper
      .oneToMany(UserDto2.class, user);

    assertEquals(user.getId(), result1.getId());
    assertEquals(user.getEmail(), result1.getUsername());
    assertEquals(user.getId(), result2.getId());
    assertEquals(user.getEmail(), result2.getEmail());
}

Notez que pour chaque classe cible, nous devons définir le nom de l’attribut cible.

Le RelationalJMapper prend seulement une classe - la classe mappée.

9.2. Utiliser des annotations

Pour l’approche des annotations, nous définirons également les classes:

public class User {
    @JMap(classes = {UserDto1.class, UserDto2.class})
    private long id;

    @JMap(
      attributes = {"username", "email"},
      classes = {UserDto1.class, UserDto2.class})
    private String email;
}

Comme d’habitude, aucune autre configuration n’est nécessaire lorsque nous utilisons des annotations:

@Test
public void givenUser__whenUseAnnotation__thenConverted(){
    RelationalJMapper<User> relationalMapper
      = new RelationalJMapper<>(User.class);
    User user = new User(1L,"[email protected]");
    UserDto1 result1 = relationalMapper
      .oneToMany(UserDto1.class, user);
    UserDto2 result2= relationalMapper
      .oneToMany(UserDto2.class, user);

    assertEquals(user.getId(), result1.getId());
    assertEquals(user.getEmail(), result1.getUsername());
    assertEquals(user.getId(), result2.getId());
    assertEquals(user.getEmail(), result2.getEmail());
}

9.3. Configuration XML

Pour la configuration XML, nous utilisons <classes> pour définir les classes cibles pour chaque attribut.

Voici notre user jmapper2.xml__:

<jmapper>
  <class name="com.baeldung.jmapper.relational.User">
    <attribute name="id">
      <value name="id"/>
      <classes>
        <class name="com.baeldung.jmapper.relational.UserDto1"/>
        <class name="com.baeldung.jmapper.relational.UserDto2"/>
      </classes>
    </attribute>
    <attribute name="email">
      <attributes>
        <attribute name="username"/>
        <attribute name="email"/>
      </attributes>
      <classes>
        <class name="com.baeldung.jmapper.relational.UserDto1"/>
        <class name="com.baeldung.jmapper.relational.UserDto2"/>
      </classes>
    </attribute>
  </class>
</jmapper>

Et passez ensuite le fichier de configuration XML à RelationalJMapper :

@Test
public void givenUser__whenUseXml__thenConverted(){
    RelationalJMapper<User> relationalMapper
     = new RelationalJMapper<>(User.class,"user__jmapper2.xml");
    User user = new User(1L,"[email protected]");
    UserDto1 result1 = relationalMapper
      .oneToMany(UserDto1.class, user);
    UserDto2 result2 = relationalMapper
      .oneToMany(UserDto2.class, user);

    assertEquals(user.getId(), result1.getId());
    assertEquals(user.getEmail(), result1.getUsername());
    assertEquals(user.getId(), result2.getId());
    assertEquals(user.getEmail(), result2.getEmail());
}

10. Conclusion

Dans ce tutoriel, nous avons appris différentes manières de configurer JMapper et d’effectuer une conversion personnalisée.

Le code source complet des exemples est disponible à l’adresse over sur GitHub .