728x90
2. 회원관리 예제
목차
- 1.비즈니스 요구사항 정리
- 2.회원 도메인과 리포지토리 만들기
- 3.회원 리포지토리 테스트 케이스 작성
- 4.회원 서비스 개발
- 5.회원 서비스 테스트
1.비즈니스 요구사항 정리
- Member(회원)에는 ID,Name
- 회원등록 , 조회 기능
- 컨트롤러 : 서비스 계층을 호출하고 결과를 뷰에 전달하는곳
- 서비스 : 비즈니스 로직이 있고 트랜잭션을 시작 , 데이터 접근 계층인 리포지토리를 호출한다
- Repository : JPA를 직접사용하는곳 , 엔티티 매니저를 사용해서 저장하고 조회한다
- Domain : 엔티티가 모여있는곳
- MemberRepository 인터페이스로 구현클래스를 변경할수 있도록 설계한다
2.회원 도메인과 리포지토리 만들기
Member(엔티티)
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;
}
}
MemberRepository(Repository 템플릿 메소드)
public interface MemberRepository {
Member save(Member member); // Member 엔티티를 DB에 저장한다
Optional<Member> findById(Long id); // 엔티티 값의 id를 찾는다 where id =?
Optional<Member> findByName(String name); // 엔티티 값의 name을 찾는다 where name=?
List<Member> findAll(); //엔티티의 값을 모두 조회 select * from Member
}
MemoryMemberRepository(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);
store.put(member.getId(), member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
//결과가 null인경우를 대비해서 Optional로 감싼다.
return Optional.of(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(); //초기화 시켜준다
}
}
- HashMap을 통한 소스!
3.회원 리포지토리 테스트 케이스 작성
MemoryMemberRepositoryTest(Repository 테스트 코드!)
class MemoryMemberRepositoryTest {
MemoryMemberRepository repository = new MemoryMemberRepository();
@AfterEach
public void afterEach(){
repository.clearStore(); //모든 테스트가 끝난후에 실행 데이터 값을 초기화
}
@Test
void save() {
//given
Member member = new Member();
member.setName("spring");
//when
repository.save(member);
Member result = repository.findById(member.getId()).get();
//then
Assertions.assertEquals(result,member);
assertThat(member).isEqualTo(result);
}
@Test
void findByName() {
//회원1
Member member1=new Member();
member1.setName("spring1");
repository.save(member1);
//회원2
Member member2=new Member();
member2.setName("spring2");
repository.save(member2);
Member result = repository.findByName("spring1").get();
assertThat(result).isEqualTo(member1);
}
@Test
void findAll() {
//회원1
Member member1=new Member();
member1.setName("spring1");
repository.save(member1);
//회원2
Member member2=new Member();
member2.setName("spring2");
repository.save(member2);
List<Member> result = repository.findAll();
assertThat(result.size()).isEqualTo(2);
}
}
}
- 테스트 코드를 통해서 Repository를 검증한다
- 항상 테스트코드 를 작성하는 법이 중요!
4.회원 서비스 개발
MemberService(service)
public class MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
//회원가입
public Long join(Member member){
//같은 이름이 있는 중복회원 x
/*//DB안의 name 을 Parameter getName넣어서 찾는다
Optional<Member> result = memberRepository.findByName(member.getName());
//값을 꺼내온다 (객체)
Member member1 = result.get();
//result의 값이 있을경우
result.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다");
} );*/
//메소드로 뽑아서 쓴다 ctrl + alt + m
//중복회원검증
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(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);
}
}
- 전체조회 , 단건조회 , 회원가입 기능이 있다!
5.회원 서비스 테스트
MemberService(service 수정..!)
public class MemberService {
//private final MemberRepository memberRepository = new MemoryMemberRepository();
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository; // 생성자 주입을 통해서 같은 MemberRepository를 사용 (인터페이스!!)
}
//회원가입
public Long join(Member member){
//같은 이름이 있는 중복회원 x
/*//DB안의 name 을 Parameter getName넣어서 찾는다
Optional<Member> result = memberRepository.findByName(member.getName());
//값을 꺼내온다 (객체)
Member member1 = result.get();
//result의 값이 있을경우
result.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다");
} );*/
...
}
MemberServiceTest(테스트코드)
class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository memoryMemberRepository;
@BeforeEach
public void beforeEach(){
//같은 MemoryMemberRepository 를 사용한다 이럴경우 같은 DB를 공유한다
memoryMemberRepository = new MemoryMemberRepository();
memberService=new MemberService(memoryMemberRepository);
}
@AfterEach
public void afterEach(){
memoryMemberRepository.clearStore(); // DB값 초기화
}
@Test
void 회원가입() {
//given
Member member = new Member();
member.setName("spring");
//when
Long saveId=memberService.join(member);
//then
Member findMember = memberService.findOne(saveId).get();
assertThat(member.getName()).isEqualTo(findMember.getName());
}
@Test
void 중복회원예외() {
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//when
memberService.join(member1);
//then
IllegalStateException result = assertThrows(IllegalStateException.class,
() -> memberService.join(member2)); // member2 가 회원가입할때 IllegalStateException 오류가 나옴
assertThat(result.getMessage()).isEqualTo("이미 존재하는 회원입니다");
}
@Test
void findMembers() {
}
@Test
void findOne() {
}
}
- 생성자 주입을 통해서 같은 MemberRepository를 사용하게 만들어준다
- DI 의존성을 주입시켜준다!
- 결국 같은 MemoryMemberRepository 를 사용하게 되서 같은 데이터 베이스가 공유된다!
- 다를 경우는 테이블이 2개가 생길수 있다!
참고자료
728x90
'Back-End > Spring' 카테고리의 다른 글
6.스프링 DB접근기술 (0) | 2020.12.29 |
---|---|
5.순수 JDBC 접근기술 (0) | 2020.12.28 |
4.회원 관리 예제 - 웹 MVC개발 (0) | 2020.12.28 |
3.스프링빈과 의존관계 (0) | 2020.12.28 |
1.스프링부트 웹개발 기초 (0) | 2020.12.25 |