회원 서비스 개발
구현할 내용
회원 가입 : 중복 회원 방지 익셉션 메서드 추가
회원 조회 : 회원 전체 조회, 회원 단건 조회
<메서드 구현>
join(Member member) : member.getId() 해도 값이 있다는 것이 보장된다! MemberRepository의 save()에서 em.persist(member)하는 순간 영속성 컨텍스트에 member객체를 넣을 때 영속성 컨텍스 (key,value)에서 key는 PK가 된다. Member 테이블의 PK는 id(name="member_id")이다. @GenerateValue는 DB마다 다른데, 어떤 것은 테이블을 아예 따로 만들어서 key를 가져오는 것도 있고, 어떤 것은 시퀀스를 만들어 넣는다. 그렇기 때문에 em.persist(member)할 때 id값이 항상 생성되있는 것이 보장된다! 왜냐하면 영속성 context할 때 값을 넣어야 하고, 그 때 구조는 (key,value)인데 key는 PK 값을 그대로 넣음과 동시에 Member 클래스 필드의 값도 채워준다.(DB에 들어가는 시점이 아니여도)
join 메서드에 중복 회원 체크 추가(메서드 추가 구현) 동시에 동일한 이름으로 회원가입하는 경우가 있다! 그러므로 멀티스레드 환경을 고려해서 DB에 member.getName()을 유니크 제약조건으로 잡아야한다! 최적화 : 단순히 갯수만을 체크해서 0보다 큰 조건으로 해줘도 된다!
findMembers() : 회원 전체 조회
findOne(Long memberId) : 회원 단건 조회
<기술 설명>
MemberService 클래스에 @Transactional(readOnly = true)로 설정
MemberService 클래스에는 읽기 메서드가 많기 때문에 상위 클래스에 @Transactional(readOnly = true)로 해주고 쓰기 메서드인 join은 @Transactional로 해준다!(디폴트값은 readOnly=false) JPA 의 모든 데이터 변경이나 로직은 모두 트랜잭션 내에서 다 실행되어야 하기 때문에 @Transactional 애노테이션 필요! @Transactinal은 자바와 스프링에서 제공하는 2가지가 있는데 스프링에 의존적인 애플리케이션을 개발하는 것이기 때문에 스프링에서 제공하는 것을 선택해야 기본 기능 외에 확장된 기능까지 사용할 수 있다! @Transactinal을 전체 클래스 레벨에 적용하면 내부의 메서드들도 다 적용이 되는데, 이 @Transactional을 조회하는 메서드에 개별로 붙이고, redOnly=true를 넣어주면 JPA가 조회하는 것에 있어서 성능이 최적화된다! 그렇기 때문에 조회하는 읽기 전용 메서드는 @Transactional(readOnly = true)로 해준다! - dirtycheck를 하지 않는 이점 - readOnly(읽기 모드)기 때문에 DB도 리소스를 많이 쓰지 않고 읽기만 함
2. 인젝션(의존 관계 주입 DI) : @Autowired 생성자 Injection 많이 사용. 생성자 하나면 생략 가능
필드 인젝션 스프링 빈에 등록된 MemberRepository를 의존 관계 주입한다!=>해당 필드 수정 어렵다!
setter 인젝션(수정자 주입) 장점 : 테스트코드 작성시에 파라미터 직접 주입해줄 수 있음. 단점 : 실제 애플리케이션이 돌아가는 시점에 누군가가 값을 셋팅해서 바뀔 수 있다! 하지만 실제로 애플리케이션 런타임에는 뭔가가 바뀔 수가 없고, 바뀌어서도 안된다!
constructor 인젝션(생성자 주입), 해당 필드는 final로 설정 생성될 때 딱 한번 주입된다! 다만, 메인 메서드에서 MemberService 객체 인스턴스 생성할 때, 파라미터로 뭐라도 넣어줘야함! 최신 스프링에서는 생성자가 딱 하나일 때는 @Autowired를 생략해도 자동으로 인젝션해준다! final로 설정하면 무조건 값이 있어야하기 때문에 값을 안 넣어주면 컴파일에러로 알려주기 때문이다!
(롬복)@AllArgsConstructor : 모든 필드를 생성자주입해준다!
(롬복)@RequiredArgsConstructor : final 붙은 필드들만 생성자주입해준다!(추천)
MemberRepository에서 EntityManager 의존 관계 주입⭐️ EntityManager는 표준 의존 관계 주입(DI) 애노테이션@PersistenceContext가 있어야 한다. 하지만 스프링 부트 JPA가 @Autowired로도 DI 지원해주기 때문에 다른 DI들과 마찬가지로 해줘도 된다! 원래 소스 :@PersistenceContext로 스프링이 JPA의 EntityManager를 생성해서 자동 주
마찬가지로 MemberRepository에서도 EntityManager 필드를 생성자 주입 가능!
이때, @PersistenceContext를 그냥 @Autowired로 해도 된다. 스프링 부트의 JPA가 지원해준다.
최종 : MemberRepository 클래스에 @RequiredArgsConstructor해주고 필드 final로 설정.
Last updated