(스프링부트) 개발 전 테스트 멤버 도메인 및 리포지토리 생성 02

안녕하세요 jju_developer입니다

지난 시간에 이어 계속하겠습니다.

(Spring Boot) 개발 전 테스트 요구사항 01

안녕하세요 jju_developer입니다.

개인 프로젝트를 혼자 진행하다가 스프링부트에 대해 더 알아봐야 할 필요성을 느껴서 차근차근 정리하면서 뽑아보고 싶네요. 비즈니스 요구 사항을 구성하는 가장 쉬운 방법

jju240.tistory.com

지난번 코딩에 이어서 회원 도메인과 리파지토리를 생성해 봅시다.

1. 도메인 패키지에 멤버 클래스 생성

2. 리포지토리 패키지에 MemberRepository 인터페이스 생성

3. Create MemoryMemberRepository는 리포지토리 패키지의 클래스를 구현합니다.

1. 도메인 패키지에 멤버 클래스 생성

먼저 구성원이 도메인이라는 패키지를 만듭니다.

그리고 여기에서 구성원을 위한 클래스를 만듭니다.

위의 요구 사항에서 회원은 ID와 NAME을 가지고 있습니다.


도메인 패키지 구성

멤버 클래스 만들기

id와 name을 비공개로 설정한 후 getter와 setter를 생성합니다.

package org.project.whipping.domain;

public class Member {

    //데이터를 저장하기 위한 id입니다.

고객이 지정한 아이디 아님 private Long id; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }

그런 다음 저장소를 만듭니다.

2. 리포지토리 패키지에 MemberRepository 인터페이스 생성

이전에 생성한 이 구성원을 저장할 저장소를 생성합니다.


MemberRepository 인터페이스 생성

인터페이스를 만듭니다.

이제 MemberRepository에서 지난 번에 언급한 두 가지 간단한 함수를 추가합니다.

인터페이스로 설계해 봅시다.

package org.project.whipping.repository;

import org.project.whipping.domain.Member;

import java.util.List;
import java.util.Optional;

public interface MemberRepository {
    //1. 회원을 저장하는 기능
    Member save(Member member);

    //2. 위에 세이브한 회원을 찾는 기능
    Optional<Member> findByID(Long id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}

여기서 기다려!
!
!
선택 사항은 무엇입니까?

개발에서 가장 일반적인 예외 중 하나는 NPE(NullPointerException)입니다.

이러한 NPE를 방지하려면 null을 확인해야 하는데, null을 확인해야 하는 변수가 많은 경우
코드가 복잡하고 번거롭습니다.

그래서 요즘 선택 과목포장용으로 사용합니다.

Java 8에서는 Optional을 사용할 수 있습니다.

사용 영점 예외 방지이를 돕기 위해 고안되었습니다.

선택 과목 null이 될 수 있는 값을 래핑하는 래퍼 클래스입니다.

참고만 해도 NPE 발생을 방지하는 데 도움이 됩니다.

(선택적으로 null 또는 NPE 값을 래핑(NullPointerException)
래퍼 클래스가 부하를 줄여주는 것 같았지만,

선택 사항에는 값을 압축 및 압축 해제하고 null의 경우 이를 대체하는 함수를 호출하는 것과 같은 오버헤드가 있습니다.


부적절하게 사용하면 시스템 성능이 저하될 수 있으므로 메서드의 반환 값이 null이 아닌 경우 Optional을 사용하지 않는 것이 좋습니다.

즉, Optional은 메서드의 결과로 null이 될 수 있으며 null로 인한 오류의 가능성이 높을 때만 반환 값으로 사용해야 한다는 점에 유의하는 것이 좋습니다!

어쨌든 돌아와

Save는 멤버를 저장하고 findAll 함수는 모든 멤버를 찾습니다.

3. Create MemoryMemberRepository는 리포지토리 패키지의 클래스를 구현합니다.

이제 구현을 만들어 봅시다.

MemoryMemberRepository라는 클래스를 만들고 구현할 것입니다.

Store라는 저장소에 저장할 Map이라는 영역을 만듭니다!

메모리에 지도가 있어야겠죠?

코드 설명은 아래에 자세히 설명되어 있습니다.

package org.project.whipping.repository;

import org.project.whipping.domain.Member;

import java.util.*;

public class MemoryMemberRepository implements MemberRepository{
    //memory 저장을 위해서 맵 사용 키는 회원아이디니까 long, 값은 Member로 합니다.

private static Map<Long, Member> store = new HashMap<>(); private static long sequence =0L; //시퀀스는 0,1,2 키값을 자동으로 만들어 주는 아이입니다!
@Override public Member save(Member member) { //회원을 저장할때 할 일!
//회원을 저장할때 시퀀스 값을 하나씩 올려주고 member.setId(++sequence); //스토어에 put으로 저장을 하고 멤버를 리턴해줄것입니다.

store.put(member.getId(),member); return member; } @Override public Optional<Member> findByID(Long id) { //아이디를 찾을때에는 어떻게 하느냐!
!
//그냥 스토어에 저장된 아이디를 겟하면 됩니다~ return Optional.ofNullable(store.get(id)); //return store.get(id);여기의 결과가 없으면 null이 될 가능성이 있기 때문에 //optional로 감싸서 반환을 해주는 것이다.

} @Override public Optional<Member> findByName(String name) { //이름을 찾을때에는 자바의 람다식을 사용하여 //filter가 계속 돌면서 멤버가 찾고자 하는 이름이랑 같다면 finaAny로 반환하기 return store.values().stream() .filter(member -> member.getName().equals(name)) .findAny(); //결과가 옵셔널의 null로 포함되어 아무것도 없으면 안함 } @Override public List<Member> findAll() { //store는 맵인데 얘는 리스트 형태로 나옴 return new ArrayList<>(store.values()); //스토어에 있는 벨류가 맴버인데 맴버가 쭉 반환하도록 리스트로 만듦 } }

이로써 우리가 구현하고자 했던 회원저장소, 아이디조회, 이름조회가 완료되었습니다.

다음에 방금 만든 코드가 제대로 작동합니다!

테스트를 해보고 잘 코딩되었는지 확인해 봅시다.

여기까지 오시느라 수고하셨습니다 !
!