Spring Boot/Spring Boot JPA-활용편1 강의 정리
[SpringBoot-JPA 활용편1] 자바 ORM 표준 JPA 프로그래밍 - 활용편1: 4. 회원 도메인 개발
조찬국
2024. 2. 26. 22:41
728x90
해당 강의는 Inflearn에 등록된 김영한님의 Spring Boot 강의입니다.
이번 시간에는 회원 도메인의 리포지토리,서비스(회원가입,조회) ,테스트케이스 작성하며 실제 JPA에서의 비즈니스 로직을 공부해보자.
1. 회원 리포지토리 개발
@Repository //스프링 빈에 등록(Component Scan 가능)
@RequiredArgsConstructor //@PersistenceContext 없이 자동으로 MemberRepostory의 생성자 주입을 함
public class MemberRepository {
//JPA 표준 annotation:
// @PersistenceContext
private final EntityManager em; //★★스프링이 엔티티 매니저 생성 후 영속성 컨테스트(PersistenceContext)에 주입
//1.회원 저장 메서드
public void save(Member member)
{
em.persist(member);
}
//2.회원 단건 조회 메서드
public Member findOne(Long id)
{
return em.find(Member.class,id);
}
//3.회원 리스트 조회 메서드
public List<Member> findAll()
{
//회원 객체 전체 조회(리스트로 조회)는 JPQL(테이블이 아닌 "객체"에 대해 SQL문구 작성) 필요.
return em.createQuery("select m from Member as m", Member.class)
.getResultList();
}
//4.회원 이름(같은 이름이면 모두) 조회 메서드
public List<Member> findByName(String name)
{
// .setParameter("name",name)로 정한 파라미터 (키,값)에 대해 ":name"로 파라미터를 받겠다는 의미
return em.createQuery("select m from Member as m where m.name= :name", Member.class)
.setParameter("name",name)
.getResultList();
}
}
2. 회원 서비스 개발
package jpabook.jpashop.service;
//★★트랜잭션은 스프링 프레임워크거를 갖고올 것★★
import org.springframework.transaction.annotation.Transactional;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Transactional(readOnly = true) //데이터 변경은 반드시 트랜잭션 안에서 실행
@RequiredArgsConstructor
public class MemberService {
//★★생성자 의존성 주입(서비스->레포)★★
//테스트 용이성: 생성자 의존성 주입을 사용하면 의존성을 모의(mock) 또는 가짜(fake) 객체로 대체하여
// 단위 테스트를 수행할 수 있다. 테스트 중에 의존 객체를 쉽게 대체할 수 있기 때문에 테스트의 효율성과 안정성이 향상된다.
private final MemberRepository memberRepository;
/* lombok의 @RequiredArgsConstructor 를 통해 자동 구현됨.
@Autowired
public MemberService(MemberRepository memberRepository)
{
this.memberRepository=memberRepository;
}
*/
//비즈니스 로직 기능: 등록, 조회
//1. 회원 등록(가입)
@Transactional
public Long join(Member member)
{
validateDuplicateMember(member); //중복 회원 검증 메서든
memberRepository.save(member); // 중복x이므로 저장
return member.getId();
}
//1.1. 중복 회원 검증 메서드
private void validateDuplicateMember(Member member) {
//이름으로 조회된 멤버들
List<Member> findMembers=memberRepository.findByName(member.getName());
//해당 이름이 존재하면 에러처리
if(!findMembers.isEmpty())
{
throw new IllegalStateException("이미 존재하는 회원입니다.");
}
}
//2. 회원 전체 조회
@Transactional(readOnly = true) //조회는 이렇게 하면 성능이 좋다
public List<Member> findAllmembers()
{
return memberRepository.findAll();
}
//3. 회원 단건 조회
@Transactional(readOnly = true)
public Member findOne(Long memberId)
{
return memberRepository.findOne(memberId);
}
}
@RequiredArgsConstructor: @PersistenceContext나 @Autowired 없이 자동으로 MemberRepostory의 생성자 주입을 함. ( 생성자가 하나면, @Autowired 를 생략할 수 있다. )
이때 반드시 final
키워드를 써야한다. final
키워드를 추가하면 컴파일 시점에 memberRepository
를 설정하지 않는 오류를 체크할 수 있다.(보통 기본 생성자를 추가할 때 발견)
3. 회원 기능 테스트
@RunWith(SpringRunner.class) //junit을 spring과 실행
@SpringBootTest //스프링 부트 컨테이너에서 테스트(autowired)
@Transactional //트랜잭션
public class MemberServiceTest {
//테스트 2개: 회원가입, 중복_회원_예외
//서비스, 레포지토리
@Autowired
MemberService memberService;
@Autowired MemberRepository memberRepository;
@Test //@Rollback(value = false) //commit까지해서 데베에 쌓였는지까지 확인 가능
public void 회원가입() throws Exception {
//given(가입하고자 하는 회원이 주어질 때)
Member member = new Member();
member.setName("CHO");
member.setAddress(new Address("seoul","낙성대역 8길","68"));
//when(그 회원을 가입 시키면?)
Long saveId=memberService.join(member);
//then(데베에서 조회한 회원과 given의 회원이 같냐?
assertEquals(member,memberRepository.findOne(saveId));
}
//
@Test(expected = IllegalStateException.class) //IllegalStateException 에러가 발생해야한다.
public void 중복_회원_예외() throws Exception {
//given(같은 이름이 회원일때)
Member member1 =new Member();
member1.setName("park");
Member member2 =new Member();
member2.setName("park");
//when(그회원 두명 모두 저장해서 IllegalStateException에러가 나면 테스트 성공)
memberService.join(member1);
memberService.join(member2); //같은 이름이므로 예외가 발생한다.
//then(테스트 실패)
fail("예외가 발생해야 합니다.");
}
}
두번째 테스트때 같은 이름을 추가하면 에러가 발생하여 중복이름으로 가입이 되면 안된다.
다음은 Test
에 사용된 기술 설명
이다.
테스트 결과
728x90