[실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발] 회원 도메인 개발

2024. 8. 27. 16:20·Back-End/JPA

[작성일: 2023. 08. 24]

 

 

회원 리포지토리 개발

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

    public List<Member> findByName(String name) {  // 회원 이름으로 조회
        return em.createQuery("select m from Member m where m.name = :name", Member.class)
                .setParameter("name", name)
                .getResultList();
    }
}

 

  • @Repository: 스프링 빈으로 등록하여 JPA 예외를 스프링 기반 예외로 예외 변환한다.
  • @PersistenceContext: 엔티티 매니저를 주입한다.(EntityManager)
  • @PersistenceUnit: 엔티티 매니저 팩토리를 주입한다.(EntityManagerFactory)

 

참고: 스프링 데이터 JPA를 사용하면 EntityManager도 주입이 가능하다.

 

 

 

 

 

회원 서비스 개발

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;

    @Transactional(readOnly = false)
    // 회원 가입
    public Long join(Member member) {
        validateDuplicateMember(member);  // 중복 회원 검증
        memberRepository.save(member);
        return member.getId();
    }

    private void validateDuplicateMember(Member member) {
        List<Member> findMembers = memberRepository.findByName(member.getName());
        if (!findMembers.isEmpty()) {
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        }
    }

    // 회원 전체 조회
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

    // 회원 1명 조회
    public Member findOne(Long id) {
        return memberRepository.findOne(id);
    }
}

 

  • @Service
  • @Transactional: 트랜잭션, 영속성 컨텍스트
    • readOnly = true: 데이터의 변경이 없는 읽기 전용 메서드에 사용, 영속성 컨텍스트를 플러시 하지 않으므로 약간 성능이 향상한다.(읽기 전용에는 전부 적용한다.)
    • 데이터베이스 드라이버가 지원하면 DB에서 성능 향상
  • @Autowired: 생성자 주입으로 많이 사용하며 생성자가 하나면 생략이 가능하다.

 

참고: 실무에서는 검증 로직이 있어도 멀티 스레드 상황을 고려해서 회원 테이블의 회원명 컬럼에 유니크 제약 조건을 추가하는 것이 안전하다. 그리고 스프링 필드 주입 대신에 생성자 주입을 사용하자.

 

  • 필드주입 말고 생성자 주입 방식을 권장한다.
  • 변경 불가능한 안전한 객체 생성이 가능하다.
  • 생성자가 하나면 @Autowired를 생략할 수 있다.
  • final 키워드를 추가하면 컴파일 시점에 memberRepository를 설정하지 않는 오류를 체크할 수 있다.

 

 

 

 

 

회원 기능 테스트

테스트 요구사항

  • 회원가입을 성공해야 한다.
  • 회원가입 할 때 같은 이름이 있으면 예외가 발생해야 한다.

 

 

 

회원가입 테스트

@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
public class MemberServiceTest {

    @Autowired MemberService memberService;
    @Autowired MemberRepository memberRepository;


    @Test
    @Rollback(value = false)
    public void 회원가입() throws Exception {
        // given
        Member member = new Member();
        member.setName("j");

        // when
        Long saveId = memberService.join(member);

        // then
        assertEquals(member, memberRepository.findOne(saveId));
    }

    @Test(expected = IllegalStateException.class)
    public void 중복_회원_예외() throws Exception {
        // given
        Member member1 = new Member();
        member1.setName("j");

        Member member2 = new Member();
        member2.setName("j");

        // when
        memberService.join(member1);
        memberService.join(member2);  // 예외가 발생해야 함.

        // then
        fail("예외가 발생해야 한다.");
    }
}

 

  • @RunWith(Springrunner.class): 스프링과 테스트 통합
  • @SpringBootTest: 스프링 부트를 띄우고 테스트(이게 없으면 @Autowired 전부 실패)
  • @Transactional: 반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고 테스트가 끝나면 트랜잭션을 강제로 롤백(이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)

 

 

 

 

 

 

 

 

 

 


🐣 출처: 인프런 김영한님 강의

 

이 글은 인프런의 김영한님 JPA 강의를 보고 작성한 글입니다.

강의를 들으면서 정리한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.

 

저작자표시 비영리 변경금지 (새창열림)
'Back-End/JPA' 카테고리의 다른 글
  • [실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발] 주문 도메인 개발
  • [실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발] 상품 도메인 개발
  • [실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발] 애플리케이션 구현 준비
  • [실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발] 도메인 분석 설계
뚜비
뚜비
1년차 백엔드&iOS 개발자의 감자 탈출 블로그 🥔🥔
  • 뚜비
    뚜비의 개발로그
    뚜비
  • 전체
    오늘
    어제
  • 글쓰기     관리
    • Devlog
      • Back-End
        • Java
        • Spring
        • JPA
        • HTTP
        • Security
        • Back-End
        • Front-End
      • 알고리즘
      • iOS
        • Swift
      • Database
      • Tips
        • Git & GitHub
        • A to Z
      • 프로젝트
      • 생각정리
  • 태그

    Swift
    데이터베이스
    자바
    게시판만들기
    변수
    Database
    의존성주입
    DB
    알고리즘
    jsp
    html
    객체
    성능최적화
    스프링
    다형성
    최주호
    javascript
    spring
    프로그래머스
    MVC
    김영한
    Java
    자바스크립트
    Spring Security
    Security
    JPA
    생성자
    sql
    HTTP
    백준
  • hELLO· Designed By정상우.v4.10.0
뚜비
[실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발] 회원 도메인 개발
상단으로

티스토리툴바