3.2.1 회원 도메인 만들기
앞선 섹션 3.1의 비즈니스 요구사항을 바탕으로, 회원 도메인과 리포지토리를 만들어보고자 한다.
src > main > java > hello.hellospring 에 domain 패키지를 만든다.
domain 패키지에 Member 클래스를 생성한다.
먼저, 2가지 데이터 요구사항이었던 ID / 이름 필드를 작성한다.
private Long id;
private String name;
- id : 고객이 정하는 id 가 아니라, 데이터를 구분하기 위해 시스템이 임의로 정하는 값
- name : 사용자가 등록하는 이름
다음으로, Getter and Setter 로 메소드를 생성한다.
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;
}
전체 코드는 다음과 같다.
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;
}
}
3.2.2 회원 리포지토리 만들기 (인터페이스)
다음으로, 회원 리포지토리 인터페이스를 만들어보자.
리포지토리는 회원 객체를 저장하는 저장소의 역할이다.
src > main > java > hello.hellospring 에 repository 패키지를 만든다.
repository 패키지에 MemberRepository 인터페이스를 작성한다.
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();
}
repository 에는 다음과 같은 4가지 기능을 만들고자 한다.
save()
- 회원이 저장소에 저장됨
findById() / findByName()
- 저장소에 저장된 id / 이름 을 찾아올 수 있음
- Optional : null인 경우 그대로 반환하지 않고, Optional로 감싸서 반환하는 방식을 선호 (Java 8 기능)
[Optional]
Null 이 될 가능성을 가진 값을 객체로 감싸는 Wrapper 클래스
Null을 직접 다룰 경우, 위험한 상황이 발생될 수 있는데,
이를 객체로 포장하여 유연한 처리가 가능하도록 한다.
(Null 을 하나의 값으로 보고 로직을 구현할 수 있음)
findAll()
- 지금까지 반환된 모든 리스트를 반환
3.2.3 회원 리포지토리 만들기 (구현체)
repository 패키지에 MemoryMemerRepository 클래스를 생성한다.
먼저, MemberRepository를 implements 해준다.
public class MemoryMemberRepository implements MemberRepository
다음으로, 앞서 작성하였던 인터페이스를 하나씩 구현해보자.
1) Save
private static Map<Long,Member> store = new HashMap<>();
private static long sequence = 0L;
- Map 을 이용하여 save 를 저장 ( key : Long id값 / value : Member)
- sequence : key 값을 생성해줌 ( 0,1,2 등)
@Override
public Member save(Member member){
member.setId(++sequence);
store.put(member.getId(), member);
return member;
}
save 하기 전에, 이름은 이미 넘어온 상태이므로,
아이디를 생성하고 map 에 저장하는 기능이 필요하다.
1) member에 저장할 때, sequence 값을 하나 올려줌
2) member 에 id값 세팅
3) store 에 member 넣기
2) findById
@Override
public Optional<Member> findById(Long id){
return Optional.ofNullable(store.get(id));
}
- store.get(id) 를 사용하여, store 에서 값을 꺼낼 수 있음
- Optional로 결과 반환 : 값이 null일 경우 Optional로 감싸서 보내주면, 나중에 클라이언트에서 사용 가능
3) findByName
@Override
public Optional<Member> findByName(String name){
return store.values().stream()
.filter(member -> member.getName().equals(name))
.findAny();
}
- name 이 파라미터로 넘어온 name 과 동일한지 확인
- 동일한 경우 filtering 함
- Optional 로 결과 반환
1) Map 에서 하나라도 찾은 경우, 찾은 값(findAny) 반환
2) Map 에서 찾지 못한 경우, null을 Optional 로 감싸서 반환
4) findAll
@Override
public List<Member> findAll(){
return new ArrayList<>(store.values());
}
- Map 이지만, List 로 반환 (List는 loop를 돌리기 편함)
- store 에 있는 values(member) 모두 반환함
전체 코드는 다음과 같다.
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<>();
private static long sequence = 0L;
@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());
}
}
+ 단축키 ) Control + Space 로 import 문을 자동으로 작성할 수 있음 (window)
김영한 '스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술' 강의를 기반으로 작성하였습니다.
'SPRING 입문 [ 코드로 배우는 스프링 부트 ]' 카테고리의 다른 글
[스프링 입문] 섹션 3.4 회원 관리 예제 (회원 서비스 개발) (0) | 2023.01.10 |
---|---|
[스프링 입문] 섹션 3.3 회원 관리 예제 (회원 리포지토리 테스트케이스 작성) (1) | 2023.01.09 |
[스프링 입문] 섹션 3.1 회원 관리 예제 (비즈니스 요구사항 정리) (0) | 2023.01.09 |
[스프링 입문] 섹션 2.3 스프링 웹 개발 기초 (API) (0) | 2023.01.09 |
[스프링 입문] 섹션 2.2 스프링 웹 개발 기초 (MVC와 템플릿 엔진) (0) | 2023.01.07 |