Konwersja encji <--> dto

0

W jaki sposób najwygodniej zamieniac encje na dto i na odwrót?

najlepiej w springu.

2

możesz zrobić sobie jakiś inteface:

@FunctionalInterface
public interface BaseConverter<F,T> {

    public T convert(F from);

    default public Collection<T> convertAll(Collection<F> fElements){
        Collection<T> convertedElement =
                fElements.stream()
                        .map(element -> convert(element))
                        .collect(Collectors.toList());

        return convertedElement;
    }
}

i potem

@Component
public class DefaultUserConverter implements BaseConverter<User, UserDTO> {

    @Override
    public UserDTO convert(User from) {
        UserDTO user = new UserDTO();
        user.setUsername(from.getUsername());
        user.setPassword(from.getPassword());
        user.setEnabled(from.getEnabled());
        return user;
    }
}

Spring ogarnia wstrzykiwanie przez generyki więc zadziała

 BaseConverter<Encja, DTO> costam
0

Znalazłem też cos takiego, co wyglada calkiem ciekawie, ale nie uzywalem : http://modelmapper.org/getting-started/

0
Biały Mleczarz napisał(a):

Dzięki, obadam.

Na razie uzywałem np. https://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html

Nic nie stoi na przeszkodzie żebyś tak zrobił - jednak, nazwa Function będzie trochę myląca, i mój converter ma zaimplementowanie konwertowanie po wielu elementach, i też jest funkcjonalny także możesz użyć z lambdy

0

hmm... no przyznaje, ze nazwa Funtion najszcżęśliwsza nie jest.
Co masz na mysli poprzez "konwertowanie po wielu elementach" ?
Bo jeśli DTO ma listę innych DTO to chyba tego nie ogarnie tylko trzeba pisac kolejny konwerter?

dzięki

0

A widzisz co robi moja domyślna metoda: **convertAll ** ?

0

Może i widzę, ale bez bicia przyznam się, że nie do końca rozumiem ;)

I w zasadzie lambd jeszcze nie zdązyłem poznac.

0
Biały Mleczarz napisał(a):

Może i widzę, ale bez bicia przyznam się, że nie do końca rozumiem ;)

I w zasadzie lambd jeszcze nie zdązyłem poznac.

Chodzi o to że od Javy 8 możesz w interface zaimplementować działającą metodą, możesz to porównać trochę do metod z klasy abstrakcyjnej. Teraz wystarczy Ci wiedzieć tyle że jeżeli zaimplementujesz w klasie A interface BaseConverter i zaimlementujesz metodę convert() to w convertAll używasz tej metody. i ta metoda convertAll, najprościej, jako parametr przyjmuje Collection czyli np: listę modeli, u mnie to będzie List<User> i idzie po każdym elemencie tej listy, i ten element czyli User convertuje na UserDTO (User -> UserDTO), potem zwraca Listę taki skonwertowanych elementów (List<User> -> List<UserDTO>)

A tak już totalnie abstrakcyjnie to przez konwertowanie po wielu elementach znaczy że mając obiekt

User user

to żeby skonwertować musisz odpalić: converter.convert(user)

Ale jak masz listę takich obiektów do skonwertowania to albo robisz to w for'ze:
```java
List<User> users;
for(User user: users){
 converer.convert(user);
}

Albo możesz to zrobić jak cywilizowany człowiek:

converter.convertAll(users)
0
niezdecydowany napisał(a):

możesz zrobić sobie jakiś inteface:

@FunctionalInterface
public interface BaseConverter<F,T> {

    public T convert(F from);

    default public Collection<T> convertAll(Collection<F> fElements){
        Collection<T> convertedElement =
                fElements.stream()
                        .map(element -> convert(element))
                        .collect(Collectors.toList());

        return convertedElement;
    }
}

i potem

@Component
public class DefaultUserConverter implements BaseConverter<User, UserDTO> {

    @Override
    public UserDTO convert(User from) {
        UserDTO user = new UserDTO();
        user.setUsername(from.getUsername());
        user.setPassword(from.getPassword());
        user.setEnabled(from.getEnabled());
        return user;
    }
}

Spring ogarnia wstrzykiwanie przez generyki więc zadziała

 BaseConverter<Encja, DTO> costam

A jak najlepiej zrobić gdy potrzeba przekazać jakis dodatkowy argument, żeby coś na tej postawie coś w środku np. sformatować?

0

czyli coś w stylu. Ale jak lepiej to zrobić?


@Component
public class DefaultUserConverter {
 
    public UserDTO convert(User from, String veryImportantParam) {
        UserDTO user = new UserDTO();
        user.setUsername(from.getUsername() + veryImportantParam );
        user.setPassword(from.getPassword());
        user.setEnabled(from.getEnabled());
        return user;
    }
}
 
0

http://mapstruct.org/ - prost i przyjemne narzędzie :)

0
Ten Zły napisał(a):

http://mapstruct.org/ - prost i przyjemne narzędzie :)

mam dystans do takich narzędzi jednak i wolałbym ręcznie.

0

I tak się właśnie tworzy gettery i settery do zarypania. Pieknie.
Polecam jednak nie robić mapperów.
Jeśli już musisz JPA używać to da się to zrobić z immutable obiektami. Wtedy bez szkód można je przesłać między warstwami.
Po prostu zrób sobie różne obiekty na rózne use casy i bierz z bazy to co potrzebujesz -> select new.
Nawet mniej kodu niż z mapperami Ci wyjdzie, a będzie bezpieczniejsze.

Może cytat z bloga Vlada:
"DTO projections are better suited for fetching custom views, while entities should only be fetched when the business flow requires to modify them."
https://vladmihalcea.com/2016/06/28/14-high-performance-java-persistence-tips/

0
@Component
public class DefaultUserConverter implements BaseConverter<User, UserDTO> {

    @Override
    public UserDTO convert(User from) {
        UserDTO user = new UserDTO();
        user.setUsername(from.getUsername());
        user.setPassword(from.getPassword());
        user.setEnabled(from.getEnabled());
        return user;
    }
}

@Component
public class DefaultUserConverter {
 
    public UserDTO convert(User from, String veryImportantParam) {
        UserDTO user = new UserDTO();
        user.setUsername(from.getUsername() + veryImportantParam );
        user.setPassword(from.getPassword());
        user.setEnabled(from.getEnabled());
        return user;
    }
}
 

@jarekr000000 co bys polecał na ten drugi case z String veryImportantParam ?

1
final class UserFormatted {
final String notVeryImportantParam;
final UserData fromDb;
[... ciach ...]
   String getUserNameFormatted() {
    return fromDB.userName + notVeryImportantParam;
   } 

}

1 użytkowników online, w tym zalogowanych: 0, gości: 1