목차
- 📌회원 리포지토리 개발
- 📌회원 서비스 개발
- 📌회원 기능 테스트
구현 기능
- 회원 등록
- 회원 목록 조회
순서
- 회원 엔티티 코드 다시보기
- 회원 리포지토리 개발
- 회원 서비스 개발
- 회원 기능 테스트
📌회원 리포지토리 개발
회원 리파지토리
package jpabook.jpashop.repository;
import jpabook.jpashop.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
@Repository // 빈 자동 등록
@RequiredArgsConstructor
public class MemberRepository {
//@PersistenceContext //스프링 엔티티메니저 생성후 여기로 인젝션
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) //JSQL,클래스 타입
.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
- 엔티티 매니져(EntutyManager) 주입@PersistenceUnit
- 엔티티 메니터 팩토리 (EntituManagerFactory) 주입
메서드 기능 설명
save()
findOne()
findeAll()
findByName()
📌회원 서비스 개발
회원 서비스
package jpabook.jpashop.service;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.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;
/*
@RequiredArgsConstructor 가 밑 생성자 자동 생성(롬북기능)
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}*/
//회원가입
@Transactional
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> findMember(){
return memberRepository.findAll();
}
public Member findOne(Long memberId){
return memberRepository.findOne(memberId);
}
}
어노테이션 기술 설명
@Service
@Transactional
- 트랜잭션, 영속성 컨텍스트
- readOnly=true : 데이터의 변경이 없는 읽기전용메서드, 영속성 컨텍스트를 플러시 하지 않아 약간의 성능이 향상 된다.
- 데이터베이스 드라이버가 지원화면 DB에서 성능 향상@Autowired
- 생성자 인젝션 많이 사용, 생성자가 하나면 생략가능
메서드 기능 설명
join()
findMembers()
findOne()
스프링 필드주입 대신 생성자주입 사용 권장
필드주입
public class MemberService {
@Autowired
MemberRepository memberRepository;
...
}
생성자 주입
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
- 생성자 주입 방식 권장
- 변경 불가능한 안전한 객체 생성 가능
- final키워드 추가시 컴파일 시점에 memberRepository를 설정하지 않는 오류를 체크할 수 있다.
📌회원 기능 테스트
테스트 요구사항
- 회원가입 성공
- 회원가입시 중복이름 있을시 예외발생
package jpabook.jpashop.service;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.repository.MemberRepository;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class MemberServiceTest{
@Autowired MemberRepository memberRepository;
@Autowired MemberService memberService;
@Test
public void 회원가입테스트() throws Exception{
//g
Member m = new Member();
m.setName("승빈");
//w
Long mId = memberService.join(m);
//t
Assert.assertEquals(m,memberRepository.findOne(mId));
}
@Test(expected = IllegalStateException.class)
public void 회원중복테스트(){
//g
Member m = new Member();
m.setName("홍길동");
Member m1 = new Member();
m1.setName("홍길동");
//v
Long member_ID = memberService.join(m);
Long member1_ID = memberService.join(m1);
//t
Assert.fail("예외가 발생해야 한다.");
}
}
📌어노테이션 정리
@RunWith(SpringRunner.class)
- 실행 방벙을 확장할 때 사용하는 어노테이션
- JUnit4.x 프레임워크가 내장된 Runner를 실행할 때 SpringRunner.class라는 확장된 클래스를 실행한다.
- 따라서 테스트시 스프링 컨테이너를 활용할 수 있게된다.
- SpringBoot2.1 버전부터 JUnit5.x로 변경되고 @SpringBootTest어노테이션에 포함되도록 변경되어 별도로 정의할 필요는 없어 졌다.
@SpringBootTest
- 통합 테스트를 제공하는 스프링부트의 기본적인 어노테이션이다.
- 여러 단위 테스트를 하나의 통합된 테스트로 수행할 때 사용한다.
- JUnit4.x 는 @RunWith 어노테이션을 같이 사용해야 정상 작동한다.(JUnit의 SpringJUnit4ClassRunner 클래스를 상속 받아 사용 해야한다.)
@Transactional
REF
'강의 > 스프링부트 JPA활용 1' 카테고리의 다른 글
스프링부트 JPA활용 1 - 주문 도메인 개발(6) (0) | 2022.06.10 |
---|---|
스프링부트 JPA활용 1 - 상품 도메인 개발(5) (0) | 2022.06.10 |
스프링부트 JPA활용 1 - 애플리케이션 구현 준비(3) (0) | 2022.06.10 |
스프링부트 JPA활용 1 - 도메인 분석 설계(2) (0) | 2022.06.10 |
스프링부트 JPA활용 1 - 프로젝트 환경설정(1) (0) | 2022.06.10 |