본문 바로가기
Framework/Spring

회원 도메인, 리포지토리 만들기

by 파2RI 2024. 1. 9.

이제부터 회원 정보를 저장하고, 저장소(repository)에서 정보를 찾을 수 있는 코드를 만들어 보겠다.

 

 

패키지

 

main>java>hello.hellospring>

domian 패키지>member클래스

repository 패키지>MemberRepository인터페이스

repository 패키지>MemoryMemberRepository클래스

 

 

 

1. member.java

 

package hello.hellospring.domain;

public class Member {

    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

기본 변수인 Long id, String name을 정의해준다.

이들은 private 변수이므로 getter, setter을 만들어준다. (단축키: alt+insert)

 

 

2. MemberRepository.java

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

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

public interface MemberRepository {

    Member save(Member member);
    Optional<Member> findById(Long id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}

 

* Optional, List 함수를 넣을 때 꼭 enter로 import를 해줘야 한다.

(@어노테이션과 같은 듯. 안하면 기능 import가 안된다)

 

Optional이란?

findById, findByName을 했을 때 결과가 null일 수 있는데,

null을 그대로 반환하기보다는 Optional로 감싸서 반환하는 것.

 

Repository(저장소)에서는

save, 즉 member 정보를 저장하고,

id, name을 통해 회원을 찾을 수 있는 기능과

findAll(), 즉 모든 회원 정보를 쫙 출력하도록 하는 기능을 만들어준다.

 

 

3. MemoryMemberRepository.java

 

MemberRepository 인터페이스를 구현하는 클래스이다.

 

public class MemoryMemberRepository implements MemberRepository

 

implements 부모 객체를 써주고,

alt+enter로 show context actions 하면 부모 객체의 메서드를 override 해올 수 있다.

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

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

public class MemoryMemberRepository implements MemberRepository {

    @Override
    public Member save(Member member) {
        return null;
    }

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.empty();
    }

    @Override
    public Optional<Member> findByName(String name) {
        return Optional.empty();
    }

    @Override
    public List<Member> findAll() {
        return null;
    }
}

 

이 상태에서 이제 각 메서드를 구체화해주면 된다.

 

 

미리 보는 최종 코드:

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import java.util.*;

public class MemoryMemberRepository implements MemberRepository {

    private static Map<Long, Member> store = new HashMap<>();
    // Map을 import 해와야 하는데, alt+enter로 할 수 있다.
    private static long sequence = 0L;
    // key 값을 생성해주는 애

    @Override
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    }

    @Override
    public Optional<Member> findByName(String name) {
         return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();
    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }
}

 

 

 

먼저 저장 공간을 만들어야 하니 이를 Map으로 구현해준다.

 

private static Map<Long, Member> store = new HashMap<>();
    // Map을 import 해와야 하는데, alt+enter로 할 수 있다.
    private static long sequence = 0L;
    // key 값을 생성해주는 애

 

key 값을 만들어주는 long sequence 변수와,

key 값마다 Member 객체를 저장하는 공간인 Map<Long, Member>() 객체를 만들어준다. 

 

 

 @Override
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    }

 

save 하는 메서드에서는

sequence, 즉 key 값을 하나 올려주고

아까 만든 store 공간에다가 member의 id 변수와 member 객체를 put 해준다.

그리고 member을 반환한다.

 

이때 key 값을 하나 올려줘서 다음 칸으로 넘어가고,

member.getId(), member이 먼저 호출되어 멤버의 id, name은 이미 넘어온 상태에서

이 값들을 store 공간에 put 한다고 생각하면 된다.

 

이때 member.setId(++sequence)에서,

member의 name은 save에서 우리가 직접 세팅하는 반면

setId는 key값에 따라 그냥 컴퓨터가 정해주는 값이다.

 

 

 @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    }

 

findById에서도 Optional로 감싸주는데,

Optional.of로 해서 Nullable, 즉 null로 반환될 가능성이 있으면 null이어도 Optional로 감쌀 수가 있다.

 

 

 public Optional<Member> findByName(String name) {
         return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();
    }

 

* 람다(lambda)

 

(매개변수) -> {실행 코드}

filter(member -> member.getName().equals(name))

 

람다에서는 함수를 값처럼 쓸 수 있게 하는데,

여기에서 member.getName()와 같은 함수를 메서드 인자/변수/반환값으로 받을 수 있다.

 

filter()을 통해 조건을 만족하는 값만 stream으로 바꿔주고,

findAny에서 Optional로 값을 반환한다.

 

 

@Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }

 

마지막으로 loop를 돌려 store의 값들을 모두 return 해준다.

 

'Framework > Spring' 카테고리의 다른 글

회원 서비스 개발  (0) 2024.01.09
회원 리포지토리 테스트 케이스 작성  (0) 2024.01.09
API  (0) 2024.01.09
IntelliJ 단축키 모음  (0) 2024.01.09
정적 컨텐츠, MVC/템플릿 엔진  (0) 2023.12.28