Leitfaden für JMapper

1. Überblick

In diesem Tutorial werden wir JMapper - ein schnelles und einfach zu bedienendes Mapping-Framework untersuchen. **

Wir werden verschiedene Möglichkeiten zum Konfigurieren von JMapper, zum Durchführen benutzerdefinierter Konvertierungen sowie zum relationalen Mapping diskutieren.

2. Maven Konfiguration

Zuerst müssen Sie die JMapper-Abhängigkeit zu unserer pom.xml hinzufügen:

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

3. Quell- und Zielmodelle

Bevor wir zur Konfiguration kommen, werfen wir einen Blick auf die einfachen Beans, die wir in diesem Tutorial verwenden werden.

Zunächst ist hier unsere Quell-Bean - eine grundlegende User :

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

Und unsere Destination Bean, UserDto:

public class UserDto {
    private long id;
    private String username;
}
  • Wir verwenden die Bibliothek, um Attribute aus unserer Quell-Bean User unserer Ziel-Bean UserDto zuzuordnen. **

Es gibt drei Möglichkeiten, JMapper zu konfigurieren: mithilfe der API, Anmerkungen und XML-Konfiguration.

In den folgenden Abschnitten gehen wir auf die einzelnen Punkte ein.

4. Verwendung der API

Hier erfahren Sie, wie Sie JMapper mithilfe der API konfigurieren.

Hier müssen wir unseren Quell- und Zielklassen keine Konfiguration hinzufügen. Stattdessen kann die gesamte Konfiguration mit __ JMapperAPI durchgeführt werden. Dies macht sie zur flexibelsten Konfigurationsmethode:

@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());
}

Hier verwenden wir die mappedClass () - Methode, um unsere zugeordnete Klasse UserDto. zu definieren. Anschließend haben wir die attribute () - Methode verwendet, um jedes Attribut und seinen zugeordneten Wert zu definieren.

Als Nächstes haben wir ein JMapper -Objekt basierend auf der Konfiguration erstellt und die Methode getDestination () verwendet, um das Ergebnis UserDto zu erhalten.

5. Anmerkungen verwenden

Mal sehen, wie wir mit der Annotation @ JMap unser Mapping konfigurieren können ** :

public class UserDto {
    @JMap
    private long id;

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

Und so verwenden wir unseren 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());
}

Beachten Sie, dass wir für das id -Attribut keinen Namen für ein Zielfeld angeben müssen, da er den gleichen Namen wie die Quell-Bean hat, während für das username -Feld erwähnt wird, dass es dem email -Feld in der User -Klasse entspricht.

Dann müssen wir nur Quell- und Ziel-Beans an unseren JMapper ** übergeben - keine weitere Konfiguration erforderlich.

Insgesamt ist diese Methode praktisch, da nur wenig Code verwendet wird.

6. Verwendung der XML-Konfiguration

Wir können auch die XML-Konfiguration verwenden, um unser Mapping zu definieren.

Hier ist unsere Beispiel-XML-Konfiguration unter 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>

Und wir müssen unsere XML-Konfiguration an JMapper übergeben:

@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());
}

Wir können die XML-Konfiguration auch als String direkt an JMapper anstelle eines Dateinamens übergeben.

7. Globale Zuordnung

  • Wir können die globale Zuordnung nutzen, wenn wir sowohl in der Quell- als auch in der Ziel-Beans mehrere Felder mit demselben Namen haben. **

Wenn wir beispielsweise ein UserDto1 haben, das zwei Felder enthält, id und email :

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

   //standard constructor, getters, setters
}

Die globale Zuordnung ist einfacher zu verwenden, da sie Feldern mit dem gleichen Namen in der User -Quell-Bean zugeordnet werden.

7.1. Verwendung der API

Für die JMapperAPI -Konfiguration verwenden wir 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. Anmerkungen verwenden

Für die Annotationskonfiguration verwenden wir @ JGlobalMap auf Klassenebene:

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

Und hier ist ein einfacher Test:

@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. XML-Konfiguration

Und für die XML-Konfiguration haben wir das Element <global/> :

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

Und dann den XML-Dateinamen übergeben:

@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. Benutzerdefinierte Konvertierungen

Lassen Sie uns nun sehen, wie Sie eine benutzerdefinierte Konvertierung mit JMapper anwenden.

Wir haben ein neues Feld age in unserem UserDto , das wir aus dem User birthDate -Attribut berechnen müssen:

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();
    }
}

Also haben wir @ JMapConversion verwendet, um eine komplexe Konvertierung ** vom Geburtsdatum von User 'auf das UserDto’s age -Attribut anzuwenden. Daher wird das age -Feld berechnet, wenn wir User zu UserDto__ zuordnen:

@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. Relationales Mapping

Zum Schluss besprechen wir das relationale Mapping. Bei dieser Methode müssen wir unseren JMapper jedes Mal mit einer Zielklasse definieren.

Wenn wir die Zielklassen bereits kennen, können wir sie für jedes zugeordnete Feld definieren und RelationalJMapper verwenden.

In diesem Beispiel haben wir eine Quell-Bean User :

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

Und zwei Ziel-Beans UserDto1 :

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

Und UserDto2 :

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

Mal sehen, wie Sie unseren __RelationalJMapper nutzen können.

9.1. Verwendung der API

Für unsere API-Konfiguration können Sie Zielklassen für jedes Attribut mit targetClasses () definieren:

@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());
}

Beachten Sie, dass wir für jede Zielklasse den Namen des Zielattributs definieren müssen.

Der RelationalJMapper benötigt nur eine Klasse - die zugeordnete Klasse.

9.2. Anmerkungen verwenden

Für den Annotationsansatz definieren wir auch die 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;
}

Wie üblich ist keine weitere Konfiguration erforderlich, wenn wir Anmerkungen verwenden:

@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. XML-Konfiguration

Für die XML-Konfiguration verwenden wir <classes> , um die Zielklassen für jedes Attribut zu definieren.

Hier ist unser 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>

Und dann übergeben Sie die XML-Konfigurationsdatei an 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. Fazit

In diesem Lernprogramm haben wir verschiedene Möglichkeiten zur Konfiguration von JMapper und zur Durchführung einer benutzerdefinierten Konvertierung kennen gelernt.

Den vollständigen Quellcode für die Beispiele finden Sie auf GitHub unter https://github.com/eugenp/tutorials/tree/master/libraries-data [.