3. [스프링 입문] - 회원 관리 예제 (코드)

김하나·2023년 5월 2일

Spring Boot

목록 보기
4/16
  • 데이터: 회원 ID, 이름
  • 기능: 회원 등록, 조회
  • 아직 데이터 저장소가 선정되지 않았다는 가정하에 진행

도메인: 예) 회원, 주문, 쿠폰 등등

public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    //식별자 id 값을 자동으로 db가 생성(=기본키 생성을 데이터 베이스에게 위임)-> IDENTITY 전략이라고 함

    private Long id;//식별 id

    //@Column(name = "username")//db에 있는 컬럼 명과 (=username) 매핑이 됨
    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;
    }



}

리포지토리: 도메인 객체를 DB에 저장하고 관리

public interface MemberRepository {
    Member save(Member member); 
    Optional<Member> findById(Long id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}
@Repository
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); //시퀀스(식별키값)을 증가시킨 값을 id에 세팅해줌->회원 저장될때마다 다른 키값을 가질 수 있게
        store.put(member.getId(),member);//map에 id저장
        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();
    }
}

리포지토리 테스트 케이스

public class MemoryMemberRepositoryTest {

    MemoryMemberRepository repository = new MemoryMemberRepository();

    @AfterEach //테스트가 종료될때 마다 db에 저장된 데이터 삭제
    public void afterEach(){ //테스트가 끝날때마다 저장소를 클리어를 해주기 위한 매서드
        repository.clearStore();
    }

    @Test
    public void save(){
        //given
        Member member = new Member();
        member.setName("Spring");
     
       //when
        repository.save(member);
     
       //then
        Member result = repository.findById(member.getId()).get();
        Assertions.assertThat(member).isEqualTo(result);
    }

    @Test
    public void findByName() {
        //given
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);
     
       //when
       Member result = repository.findByName("spring1").get();
  
       //then
        Assertions.assertThat(result).isEqualTo(member1);
    }
    @Test
    public void findAll(){
        //given
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);
      
       //when
        List<Member> result = repository.findAll();
       
       //then
        Assertions.assertThat(result.size()).isEqualTo(2);
    }
}

서비스: 핵심 비즈니스 로직 구현되는 곳

//서비스 클래스의 매서드들은 비지니스와 가까운 이름을 사용해서 만들어줘야함

@Transactional
//@Service
public class MemberService {


    private final MemberRepository memberRepository;

    //멤버서비스는 멤버 리포지토리가 필요하므로 의존성 주입을 통해 연결
    /** DI 의존성 주입은 총 3가지 방법 존재
    방법1. 생성자를 통해서 주입되는 것이기 때문에 생성자 주입이라고도 함 */
  @Autowired
   public MemberService(MemberRepository memberRepository){
    this.memberRepository = memberRepository;
 }

 

    //회원가입 로직
    public Long join(Member member) {
            //같은 이름이 있는 중복회원 불가  ctrl + alt +v
            vaildateDuplivateMember(member); //중복회원 검증
            memberRepository.save(member);
            return member.getId();
    }

     //중복회원 확인 로직
    private void vaildateDuplivateMember(Member member){
        memberRepository.findByName(member.getName()).ifPresent(m-> {
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        });
    }

  //회원 전체 조회 로직
    public List<Member> findMembers(){
   return memberRepository.findAll();
    }
    public Optional<Member>findOne(Long memberId){
        return memberRepository.findById(memberId);
    }

}

컨트롤러: 웹 MVC의 컨트롤러 역할

@Controller
public class MemberController {

    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService){
        this.memberService = memberService;
    }


    @GetMapping("/members/new")
    public String createForm(){
        return "members/createMemberForm";
    }

    @PostMapping(value = "/members/new")
    public String create(MemberForm form) {
        Member member = new Member();
        member.setName(form.getName());
        System.out.println("member = "+member.getName());
        memberService.join(member);
        return "redirect:/";
    }

    @GetMapping("/members")
    public String list(Model model){
       List<Member> members = memberService.findMembers();//멤버 전체 조회
        model.addAttribute("members",members);
        return "members/memberList";
    }

}

0개의 댓글