@Repository란?

<aside> 💡 Java 및 Spring Framework에서 어노테이션이 붙은 클래스가 데이터 엑세스 및 지속성 작업을 담당하는 저장소임을 나타내는데 사용되는 주석

</aside>

회원 레퍼지토리 개발

@Repository
public class MemberRepository {
	@PersistenceContext // JPA EntityManager를 주입해준다. 
	private EntityManager em;

	// 만약 EntityManagerFactory를 직접 제어하고 싶다면??
	// @PersistenceUnit private EntityManagerFactory emf;
	
	public void save(Member member) {
		em.persist(member); // 영속성 컨텍스트에 넣기
	}
	
	// 1개 조회 
	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();
	}
}

회원서비스

@Service
@Transactional(readOnly = true)
// 조회는 readOnly = true 설정해서 성능 향상 (데이터 변경이 안된다)
public class MemberService {

	@Autowired
	private MemberRepository memberRepository;

	// 회원 가입 (성공시 id를 반환한다.)
	@Transactional
	public Long join(Member member) {
		validateDuplicateMember(member); // 중복 회원 검증 
		memberRepository.save(member); 
		return member.getId();
	}

	// DB에 동시에 insert 하면 ?...    
	// 최후의 방어를 위해서 memberName을 unique 제약 조건으로 걸어주는 방법 있다. 
	private void validateDuplicateMember(Member member) {
		List<Member> findMembers = memberRepository.findByName(member.getName());
		if (!findMembers.isEmpty()) {
			throw new IllegalStateException("이미 존재하는 회원입니다.");
		}
	}

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

	private Member findOne(Long memberId) {
		return memberRepository.findOne(memberId);
	}

}

Injection 3가지 방법

  1. 필드 Injection (주입하기 까다롭다)

  2. setter Injection (주입하기 좋지만, Runtime 시점에 누군가가바꿔치기 할 수 있다. 그럴가능성이 적겠지만)

  3. 생성자 Injection (주입하기 좋고, 값을 세팅안하면 컴파일 에러를 통해 명확하게 알 수 있다.)

    (생성자 Injection → 롬복 → @RequiredArgsConstructor) 아래의 생성자 주입을 롬복으로 대체하길 권장한다고 한다.

private final MemberRepository memberRepository;

@Autowired
public MemberService(MemberRepository memberRepository) {
	this.memberRepository = memberRepository;
}
	@PersistenceContext
	private EntityManager em;

// 이거 역시 생성자 주입 방식으로 변경할 수 있다. (내부적으로 Spring JPA가 주입해준다.)
@RequiredArgsConstructor
public ~~~ {
	private final EntityManager em;
}

회원 기능 테스트

cmd + shift + T : 테스트 코드 자동 생성

회원 가입 테스트