[Java] Optional 관련..

Aiden Shin·2020년 2월 25일
5

Spring Data JPA 사용 시 Repository에서 리턴 타입을 Optional로 바로 받을 수 있도록 지원하고 있습니다.

Optional을 사용하면 반복적인 null 체크를 줄일 수 있기 때문에 잘 사용하면 매우 편리한 것 같습니다.

Optional 관련하여 사용법을 간략하게 정리해봤습니다.


1. get() 사용 관련

    // AS-IS
    @Override
    public Sample getSample(final Long id) {
        // 값이 없으면 NoSuchElementException
        return sampleRepository.findById(id).get();
    }

.get()의 경우 결과값이 null일 경우 NoSuchElementException 발생

orElseThrow()를 통해 값이 없을 경우 예외를 던져주거나
orElse , orElseGet를 통해 값이 없을 경우 값을 지정

    //Optional 결과 값이 없을 때 처리
    
    // throw Exception
    return sampleRepository.findById(id)
                           .orElseThrow(IllegalArgumentException::new);
    
    return sampleRepository.findById(id)
                           .orElseThrow(() -> new IllegalArgumentException("no such data");
    
    
    // null Return
    return sampleRepository.findById(id)
                           .orElse(null);
    
    // 비어있는 객체로 Return
    return sampleRepository.findById(id)
                           .orElseGet(Sample::new);

2. Optional 에서 값 바로 받기

Repository에서 Optional을 반환하는 경우 원하는 값이 있으면 원하는 객체로 받고 없으면 Exception처리를 하는 패턴을 사용

Optional은 NPE 방어를 위한 코드를 쉽게 사용하기 위해 사용

    // AS-IS
    @Override
    @Transactional
    public Sample updateSample(Long sampleId) {
    
        Optional<Sample> sample = sampleRepository.findById(sampleId);
    
        if(!sample.isPresent()) {
            throw new IllegalArgumentException();
        }
     // 위의 코드를 orElseThrow 사용을 통해 한줄로 줄일 수 있음
    
        ...
    
        return sample.get();
    }
    //  TO-BE
    @Override
    @Transactional
    public Sample updateSample(Long sampleId) {
    
        Sample sample = sampleRepository.findById(sampleId)
                                         .orElseThrow(IllegalArgumentException::new);        .
    
        ...
    
        return sample;
    }

3. ifPresent() 사용

    // AS-IS
    Optional<User> user = userRepository.findById(userId);
    if(user.isPresent()) {
        vo.setUsername(user.get().getUsername());
        vo.setUserNm(user.get().getName());
    }

    //  TO-BE
    Optional<UserVO> user = userRepository.findById(userId);
    user.ifPresent(u -> {
        vo.setUsername(u.getUsername());
        vo.setUserNm(u.getName());
    });
profile
예전 블로그: https://shinilhyun.github.io/

0개의 댓글