ModelMapper 적용

Yuri Lee·2020년 11월 13일
0

ModelMapper

Why?

    public void updateProfile(Account account, Profile profile) {
        account.setUrl(profile.getUrl());
        account.setOccupation(profile.getOccupation());
        account.setLocation(profile.getLocation());
        account.setBio(profile.getBio());
        account.setProfileImage(profile.getProfileImage());
        accountRepository.save(account); // save를 하게 되면 update가 발생함
        // TODO 문제가 하나 더 남았습니다.
    }
    public void updateNotifications(Account account, Notifications notifications) {
        account.setStudyCreatedByWeb(notifications.isStudyCreatedByWeb());
        account.setStudyCreatedByEmail(notifications.isStudyCreatedByEmail());
        account.setStudyUpdatedByWeb(notifications.isStudyUpdatedByWeb());
        account.setStudyUpdatedByEmail(notifications.isStudyUpdatedByEmail());
        account.setStudyEnrollmentResultByEmail(notifications.isStudyEnrollmentResultByEmail());
        account.setStudyEnrollmentResultByWeb(notifications.isStudyEnrollmentResultByWeb());
        accountRepository.save(account);
    }

이런 부분들을 ModelMapper 를 사용하여 간결하게 줄여보자! 😎😎

의존성 추가

<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.6</version>
</dependency>

여러번 매번 만들어서 사용할 필요가 없기 때문에 Bean으로 등록하자.

프로퍼티에 들어있는 값을 account에 담아주고 있다. 맵에 입장에서 소스는 profile에 있는 데이터이고 destination는 account이다.

    public void updateNotifications(Account account, Notifications notifications) {
    	
    	modelMapper.map(notifications, account);
    	
        //account.setStudyCreatedByWeb(notifications.isStudyCreatedByWeb());
        //account.setStudyCreatedByEmail(notifications.isStudyCreatedByEmail());
        //account.setStudyUpdatedByWeb(notifications.isStudyUpdatedByWeb());
        //account.setStudyUpdatedByEmail(notifications.isStudyUpdatedByEmail());
        //account.setStudyEnrollmentResultByEmail(notifications.isStudyEnrollmentResultByEmail());
        //account.setStudyEnrollmentResultByWeb(notifications.isStudyEnrollmentResultByWeb());
        accountRepository.save(account);
    }

여기서는 함정이 있다. 데이터를 맵핑할 때 ModelMapper 가 이해를 잘 못할 수도 있다.

다음과 같은 에러가 발생한다! 😭😭

com.yuri.studyolle.settings.Notifications.isStudyEnrollmentResultByEmail()
com.yuri.studyolle.settings.Notifications.isStudyUpdatedByEmail()
com.yuri.studyolle.settings.Notifications.isStudyCreatedByEmail()

Notifications안에 3개의 값이 들어있는데 이를 account에다가 적용하려고 하는데 Mapping 되어있는 것을 잘 못 찾고 있는 것이다. Notifications의 isStudyEnrollmentResultByEmail()를 isStudyEnrollmentResultByEmail 다가 넣어야 하는데 Account.setEmail() 에 넣으려고 하는 것이다.

즉 잘 구분하지 못한다. 따라서 ModelMapper를 잘 설정해줘야 한다.

토크나이저 설정

    // ModelMapper
    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
                .setDestinationNameTokenizer(NameTokenizers.UNDERSCORE)
                .setSourceNameTokenizer(NameTokenizers.UNDERSCORE);
        return modelMapper;
    }
  • UNDERSCORE(_)를 사용했을 때에만 nested 객체를 참조하는 것으로 간주하고 그렇지 않은 경우에는 해당 객체의 직속 프로퍼티에 바인딩 한다.

Notifications.java
Notification는 Bean이 아니다. 생성자가 직접 호출해서 만들어낸 객체들이기 때문에 Bean이 아니다. 그러므로 주입받지 못한다.

느낀점

이렇게까지 코드가 간단해진다는 게 너무 신기함 😮😮


출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발

profile
Step by step goes a long way ✨

0개의 댓글