Project/9uin

spring boot 사이드 프로젝트[5] : service, repository 초기 작성

attlet 2023. 5. 23. 17:46

데이터베이스를 entity를 이용해 다루는 레이어 repository, 그리고 이 repository를 이용해 비즈니스 로직을 구현하는 service레이어의 초기 작성을 한다.

 

user의 repository, service를 작성하기 위해 user도메인 안에 repository, service 패키를 만들어 그 밑에 클래스 파일을 생성한다. 

 

Repository 작성

 

 

repository는 이렇게 jpaRepository를 상속받은 인터페이스로 생성한다. 이렇게 인터페이스로 만들어도 service에서 의존성 주입을 통해 사용이 가능한 건 spring data jpa가 이 인터페이스를 기반한 구현체를 실행 시 생성해서 프록시 객체로 주입해주는 것 때문이다. 구현체에는 jpaRepository 에 정의되어있는 여러 쿼리 메서드를 사용할 수 있다. 물론 더 디테일한 쿼리를 사용하고 싶기에, 나중에 커스텀 쿼리 클래스를 작성할 것이다.

 

 

Service 작성

 

 

앞으로도 이 구조를 만나게 될 가능성이 높은 것 같다. Service 인터페이스와 그 인터페이스의 구현체를 따로 이렇게 만들어서 사용하게된다. 굳이 이렇게 할 필요가 있는 지 생각이 들 수 있다. 

 

https://cumbersome-line-9d7.notion.site/DIP-cf65505010534714a556bc8534e57d31

 

DIP(의존성 역전 원칙)

DIP는 객체는 저수준 모듈보다 고수준 모듈에 의존해야한다는 원칙이다.

cumbersome-line-9d7.notion.site

 

스프링 부트를 공부할 때 찾게 된 원리 중 하나인 DIP를 근거로 설계한 것이다. 자세한 내용은 내가 공부하며 작성한 노션을 확인하거나 검색을 하면 이해가 빠를 것이다. 

 

그 다음 impl에 로직을 작성한다. 일단 기본적인 crud를 작성했다.

 

@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    @Autowired
    UserServiceImpl(UserRepository userRepository){
        this.userRepository = userRepository;
    }
    @Override
    public ResponseUserDto getUser(Long id) {
        User user = userRepository.findById(id).get();
        ResponseUserDto responseUserDto = new ResponseUserDto();

        responseUserDto.setId(user.getId());
        responseUserDto.setUser_id(user.getUser_id());
        responseUserDto.setMail(user.getMail());

        return responseUserDto;
    }

    @Override
    public ResponseUserDto createUser(UserDto userdto) {
        User user = User.builder()
                .user_id(userdto.getUser_id())
                .password(userdto.getPassword())
                .mail(userdto.getMail())
                .build();                      //builder pattern

        User savedUser = userRepository.save(user);
        ResponseUserDto responseUserDto = new ResponseUserDto();
        responseUserDto.setId(savedUser.getId());
        responseUserDto.setUser_id(savedUser.getUser_id());
        responseUserDto.setMail(savedUser.getMail());

        return responseUserDto;
    }

    @Override
    public ResponseUserDto updateUser(Long id, UserDto userdto) {
        User user = userRepository.findById(id).get();   //예외처리 추가 가능.
        user.setUser_id(userdto.getUser_id());
        user.setPassword(userdto.getPassword());
        user.setMail(userdto.getMail());

        User updatedUser = userRepository.save(user);
        ResponseUserDto responseUserDto = new ResponseUserDto();
        responseUserDto.setId(updatedUser.getId());
        responseUserDto.setUser_id(updatedUser.getUser_id());
        responseUserDto.setMail(updatedUser.getMail());

        return responseUserDto;
    }

    @Override
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }

}

user 데이터 하나를 read, create, update, delete하는 간단한 로직이다. 물론 이 과정에서 암호화, 디테일한 쿼리 등의 추가작업이 필요할 것이다. 

 

객체 생성 시 빌더(builder)패턴으로 생성하는 모습을 볼 수 있다. 이는 Effective java를 읽다가 배운 내용을 응용해본 것이다. 

 

https://brainy-enquiry-6c8.notion.site/2-d1ac266e13ec4e679fc17e700b25cb1f

 

아이템[2] : 생성자에 매개변수가 많다면 빌더를 고려하라

생성자가 만약 20개가 넘고, 생성할 때 몇몇 필드는 의미가 없는 값이라면 어떨까.

brainy-enquiry-6c8.notion.site

 

다음은 좀 더 디테일한 쿼리를 위해 querydsl을 설정할 것이다.