쌓고 쌓다

회원 도메인과 리포지토리 만들기 본문

프로그래밍/spring

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

승민아 2023. 4. 29. 19:13

요구사항

  • 데이터: 회원ID, 이름
  • 기능: 회원 등록, 조회
  • 아직 데이터 저장소가 선정되지 않아 메모리 기반으로 할 것임

 

일반적인 웹 애플리케이션 구조 (인프런-김영한)

  • 컨트롤러: 웹 MVC의 컨트롤러
  • 서비스: 핵심 비즈니스 로직 구현 (회원 중복가입 불가 로직 등...)
  • 리포지토리: DB에 접근, 도메인 객체를 DB에 저장하고 관리
  • 도메인: 비즈니스 도메인 객체 (EX. 회원, 주문, 쿠폰 등 DB에 저장되고 관리됨)

 

클래스 의존관계(인프런-김영한)

 

회원 클래스

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

id는 사용자가 정한는 id가 아니라 시스템이 시퀀스로 저장할 것임.

 

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

Optinal?

findById, findByName 메소드 리턴 값. 가져온 값이 널일 수 있어서 

보통 null 값을 Optional로 감싸서 반환하는걸 선호한다.

복잡한 구현 없이도 널 값으로 인해 발생하는 예외를 다룰 수 있기 때문.

 

따라서 참조 변수의 값이 null이 될 가능성이 있다면 ofNullable() 메소드를 사용해 Optional 객체를 생성하는 것이 좋다.

ofNullable() 메소드는 명시된 값이 null이 아니면 명시된 값을 가지는 Optional 객체를 반환하며, 명시된 값이 null이면 비어있는 Optional 객체를 반환함.

 

참조: http://www.tcpschool.com/java/java_stream_optional

 

 

MemberRepository.java

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

 

1. 람다식

(매개변수, ...) -> { 실행문 }

매개변수가 하나인 경우 괄호를 생략할 수 있다.

람다식의 바디부분(실행문)에 하나의 표현식만 오는 경우 중괄호를 생략할 수 있다.

중괄호가 생략된 람다식에서는 세미콜론(;)을 붙이지 않음.

만약, 'return'문을 작성한 경우 중괄호를 생략할 수 없다.

 

2. 스트림

자바에서 배열이나 컬렉션을 사용할 때 저장된 데이터에 접근하기 위해서 반복문이나 반복자(Iterator)를 사용하여 접근했고. 이 방법은 코드가 길고 가독성이 떨어진다.

그 문제점의 해결법이 스트림이다.

 

스트림은 아래의 단계를 거쳐 동작한다.

[스트림의 생성 -> 스트림의 중개 연산 -> 스트림의 최종 연산]

중개 연산의 결과는 Stream 형태로 결과를 반환하기에 연속적으로 연결 사용이 가능함.

 

(MemberRepository에 사용된 메소드들 위주 설명)

  2-1 스트림 생성

컬렉션에서는 stream() 메소드로 스트림을 생성할 수 있다.

 

  2-2 중개 연산

스트림 필터링

filter(predicate) : 해당 스트림에서 조건(predicate)에 맞는 요소로만으로 구성된 새로운 스트림 반환.

 

  2-3 최종 연산

요소의 검색

findAny() : 해당 스트림에서 첫 번째 요소를 참조하는 Optional 객체를 반환.

 

참조: https://mine-it-record.tistory.com/477

Comments