프로그래밍 언어/Spring

<SpringBoot> LMS 프로젝트 9. Repository, service 계층 구현 및 테스트

창조적생각 2021. 12. 13. 14:35

계층형 구조 

controller,web: 웹 계층

service : 비즈니스 로직, 트랜잭션 처리

repository:JPA를 직접 사용하는 계층, 엔티티 매니저 사용

domain: 엔티티가 모여있는 계층, 모든 계층에서 사용

 

개발 순서 : 서비스 -> 리포지토리 계층을 개발하고 테스트 케이스를 작성해서 검증, 마지막에 웹 계층 적용

MemberRepository와 MemberService 구현

 

1. MemberRepository

레포지토리 계층에서는 DB저장과 DB에서 조건에 맞는 데이터를 불러오는 기능을 넣어둔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.example.lms_jpa.repository;
 
import com.example.lms_jpa.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
 
import javax.persistence.EntityManager;
import java.util.List;
 
@Repository
@RequiredArgsConstructor
public class MemberRepository {
    private final EntityManager em;
 
    //회원 저장(회원 가입)
    public void save(Member member){
        em.persist(member);
    }
    //회원 하나 찾기
    public Member findOne(Long id){
        return em.find(Member.class,id);
    }
    //회원 전체 찾기
    public List<Member> findAll(){
        return em.createQuery("select m from Member m",Member.class)
                .getResultList();
    }
    //회원 중복 id검사를 위한 user_id를 가지고 
    public List<Member> findByMember(String user_id){
        return em.createQuery("select m from Member m where m.user_id = :user_id",Member.class)
                .setParameter("user_id",user_id)
                .getResultList();
    }
}
cs

*RequiredArgsConstructor

롬복에서 생성자 주입을 자동으로 해주는 어노테이션이다.

이 어노테이션 없이 직접 생성자 주입을 통해서 구현할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.lms_jpa.repository;
 
import com.example.lms_jpa.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
 
import javax.persistence.EntityManager;
import java.util.List;
 
@Repository
@RequiredArgsConstructor
public class MemberRepository {
 
    private final EntityManager em;
 
    public MemberRepository(EntityManager em) {
        this.em = em;
    }
 
    //회원 저장(회원 가입)
    public void save(Member member){
        em.persist(member);
    }
    //회원 하나 찾기
    public Member findOne(Long id){
        return em.find(Member.class,id);
    }
    //회원 전체 찾기
    public List<Member> findAll(){
        return em.createQuery("select m from Member m",Member.class)
                .getResultList();
    }
    //회원 중복 id검사를 위한 user_id를 가지고 찾기
    public List<Member> findByMember(String user_id){
        return em.createQuery("select m from Member m where m.user_id = :user_id",Member.class)
                .setParameter("user_id",user_id)
                .getResultList();
    }
}
cs

 

2. MemberService

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.example.lms_jpa.service;
 
import com.example.lms_jpa.domain.Member;
import com.example.lms_jpa.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.List;
 
@Service
@Transactional
@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;
    
    //회원가입 및 아이디중복검사
    public Long join(Member member){
        validateDuplicatedMember(member);
        memberRepository.save(member);
        return member.getId();
    }
    //
    private void validateDuplicatedMember(Member member){
        List<Member> findMembers = memberRepository.findByMember(member.getUser_id());
        if(!findMembers.isEmpty()){
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        }
    }
    //회원 전체조회
    public List<Member> findMembers(){
        return memberRepository.findAll();
    }
    //회원 한명 조회
    public Member findOne(Long id){
        return memberRepository.findOne(id);
    }
}
cs

 

*transactional(readOnly =true)

-> 조회하는 기능은 readOnly로 해서 최적화 가능, transactional의 readOnly 기본값은 false이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.lms_jpa.service;
 
import com.example.lms_jpa.domain.Member;
import com.example.lms_jpa.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.List;
 
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;
 
    @Transactional
    //default값이 false임으로 등록기능에 추가해준다.
    public Long join(Member member){
        validateDuplicatedMember(member);
        memberRepository.save(member);
        return member.getId();
    }
    private void validateDuplicatedMember(Member member){
        List<Member> findMembers = memberRepository.findByMember(member.getUser_id());
        if(!findMembers.isEmpty()){
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        }
    }
    //회원 전체조회
    public List<Member> findMembers(){
        return memberRepository.findAll();
    }
    //회원 한명 조회
    public Member findOne(Long id){
        return memberRepository.findOne(id);
    }
}
 
cs

 

3. MemberServiceTest

 

검증할 기능 

1) 가입 후 가입한 아이디로 회원 조회가 되는지

2) 가입 시 중복 검사가 제대로 실행되는지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.example.lms_jpa.service;
 
import com.example.lms_jpa.domain.Member;
import com.example.lms_jpa.repository.MemberRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
 
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
class MemberServiceTest {
    @Autowired
    MemberRepository memberRepository;
    @Autowired
    MemberService memberService;
    @Test
    public void 회원가입() throws Exception{
        Member member = new Member();
        member.setName("서성우");
        member.setUser_id("operstu1");
 
        Long saveIdName = memberService.join(member);
 
        assertEquals(member,memberService.findOne(member.getId()));
    }
    @Test
    public void 중복확인() throws Exception{
        Member member1 = new Member();
        member1.setUser_id("operstu1");
 
        Member member2 = new Member();
        member2.setUser_id("operstu1");
 
 
        memberService.join(member1);
        try{
            memberService.join(member2);//예외 터져야 함
        }catch(IllegalStateException e){
            return;
        }
 
        fail("예외가 발생해야합니다!!");
 
    }
}
cs

실행결과

 

 

 

 

 

 

 

 

 

728x90