본문 바로가기

Spring

[Spring] 회원 관리 Backend 개발(1)_회원 등록&조회

회원 관리를 위한 백엔드 개발의 첫 시작이다.

간단한 회원 등록, 조회가 가능한 로직으로 구현할 예정이다.

 

 

1. 로직

- 데이터: 회원 ID, 이름

- 기능: 회원 등록, 조회

 

 

 

2. 계층 구조

- Controller: 웹 MVC의 컨트롤러

- Service: 핵심 비즈니스 로직 구현

- Repository: DB에 접근, 도메인 객체를 DB에 저장, 관리

- domain: 비즈니스 도메인 객체(DB에 저장, 관리)

 

 

 

3. 클래스 의존 관계

- MemberService -> MemberRepository(interface) <- MemoryMemberRepository

 

아직은 데이터 저장소를 따로 설정하지 않았기 때문에 변경에 용이한 인터페이스로 구현할 것이다.

 

 

 

4. 클래스별 기능

● domain

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;
}
}

getId()는 값을 반환하는 것이고, setId()는 값을 설정하는 것이다.

 

* getter, setter의 사용 목적

OOP의 가장 큰 특징은 객체의 무결성을 위해 데이터를 캡슐화하는 것이다.

이는 외부 접근을 통해 데이터 변경을 막기 위함인데 getter, setter은 이에 반대되는 시스템이다.

메서드를 통해 외부 접근이 가능하게 하기 때문이다.

그러나, 바로 외부에서 접근하는 것과 달리 메서드를 통해 접근하므로 

매개 값을 검증하여 유효 값만 저장할 수 있고(Getter의 역할)

외부에서 데이터를 읽을 때 필드 값을 가공할 수 있다.(Setter의 역할)

클래스 자체는 private 범위로 하여 외부로부터 보호하고 

메서드를 통해 접근하여 필드 값을 안전하게 변경하여 사용할 수 있다. 

 

● 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();

}

- save() -> member값을 저장(id, name)

- findById() -> id값을 찾아서 반환

                       Optional로 감싸서 null값이 반환되어도 오류 X

- findByName() -> name값을 찾아서 반환

- findAll() -> member의 모든 값을 list형식으로 반환

 

● MemoryMemberRepository

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());
}

public void clearStore(){
store.clear();
}
}

findByName()에서 사용된 여러 메서드를 살펴볼 것이다.

- values(): Enum클래스의 메서드로 해당 열거체의 모든 상수를 저장한 배열을 생성 후 반환한다.

                이때 상수는 id를 의미하며 store에 저장된 id를 list형식으로 열거하여 생성하고 반환하는 역할을 한다.

 

- stream(): 스트림 인스턴스 생성

- filter(): 가공(필터링) -> member객체의 name값이 실제 입력한 name과 같은지 확인(같으면 통과)

*스트림을 생성한 이유: 특정값을 추출하여 List로 생성하기 위해

 

- findAny(): 조건에 맞는 요소 반환(가장 먼저 탐색되는 값 반환 -> 병렬 처리 시 실행할 때마다 다른 값)

  *findFirst(): 조건에 맞는 요소를 순서에 맞게 번환(병렬 처리 시에도 실행할 때마다 같은 값)

 

-findAll(): 위의 메서드에서 생성된 store의 list를 반환

 

회원 관리를 위한 클래스 구현 방법, 의존 관계, 메서드에 대해 잘 이해할 수 있는 시간이었다.

 

 

참고: 인프런-스프링 입문-코드로 배우는 스프링 부트, 웹 MVC, DB접근 기술

#Backend #웹 #회원관리 #Web #IT