-
[스프링부트/웹 애플리케이션 개발]회원 repository, 회원 service 개발, 인젝션 방법 3가지, @RequiredArgsConstructor스프링&스프링부트 2023. 1. 4. 17:33
- 구현 기능 : 회원 등록 / 회원 목록 조회
1. 회원 repository
package jpabook.jpashop.repository; import jpabook.jpashop.domain.Member; import org.springframework.stereotype.Repository; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.util.List; @Repository public class MemberRepository { @PersistenceContext private EntityManager em; //스프링이 EntityManager를 만들어서 주입해 줌 //@PersistenceUnit //private EntityManagerFactory emf; //EntityManagerFactory도 직접 주입 받을 수 있음 public void save(Member member) { em.persist(member); } //EntityManager 사용 //persist하면 영속석 context에 member entity를 넣는다 //트랜잭션이 commit하는 시점에 DB에 반영된다(insert 쿼리) //단건 조회 public Member findOne(Long id) { return em.find(Member.class, id); //em.find(타입, PK) } //전체 조회 public List<Member> findAll() { //List<Member> result = em.createQuery("select m from Member m", Member.class).getResultList(); //return result; return em.createQuery("select m from Member m", Member.class).getResultList(); //JPQL 문법 사용, from의 대상은 테이블 아니고 entity } //이름으로 조회 public List<Member> findByName(String name) { return em.createQuery("select m from Member m where m.name = :name", Member.class) .setParameter("name", name) .getResultList(); } }
2. 회원 service
package jpabook.jpashop.service; import jpabook.jpashop.domain.Member; import jpabook.jpashop.repository.MemberRepository; import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional(readOnly = true) //@Transactional //JPA의 모든 데이터 변경이나 어떤 로직들은 트랜잭션 안에서 실행되어야 함 //스프링이 제공하는 트랜잭션 사용하는 것 권장 > 활용할 수 있는 옵션이 많음 @RequiredArgsConstructor public class MemberService { //인젝션 방법1. 필드 인젝션 //@Autowired //private MemberRepository memberRepository; //MemberRepository를 사용하기 위해 @Autowired로 injection //스프링이 스프링 빈에 등록되어있는 MemberRepository를 주입해준다. //보통 많이 사용하지만 단점이 많음, 필드+프라이빗 > 변경 불가능 //인젝션 방법2. setter인젝션 //private MemberRepository memberRepository; //@Autowired //public void setMemberRepository(MemberRepository memberRepository) { // this.memberRepository = memberRepository; //} //장점 : testcode 작성 시 목과 같은 것들을 직접 주입해 줄 수 있음 //단점 : (치명적) 실제 application 실행할 때 누군가가 setMemberRepository을 변결할 수 있다. //인젝션 방법3.1 생성자인젝션 //private final MemberRepository memberRepository; //더 이상 변경할 일 없기 때문에 필드를 final로 변경 //@Autowired //최신 스프링의 경우 생성자가 1개일 경우 자동으로 @Autowired, 따라서 생략 가능 //public MemberService(MemberRepository memberRepository) { // this.memberRepository = memberRepository;} //최근에 가장 많이 사용 됨 //중간에 변경할 수 없고 testcase에 용이 //인젝션 방법 3.2 생성자인젝션+@RequiredArgsConstructor private final MemberRepository memberRepository; //lombok > @RequiredArgsConstructor > final 있는 필드를 가지고 생성자 만들어 줌 //회원 등록 @Transactional //readOnly = false가 기본값 public Long Join(Member member) { //중복 회원 검증 비즈니스 로직 추가 validateDuplicateMember(member); memberRepository.save(member); return member.getId(); } private void validateDuplicateMember(Member member) { //Exception List<Member> findMembers = memberRepository.findByName(member.getName()); if (!findMembers.isEmpty()) { throw new IllegalStateException("이미 존재하는 회원입니다."); } //동시에 validateDuplicateMember 호출하면 문제 발생 //비즈니스 로직이 있다고 해도 실무에서는 최후의 방어가 한 번 더 필요 //멀티쓰레드 등과 같은 상황을 고려해 database에 유니크제약 조건 추가 } //회원 전체 조회 //@Transactional(readOnly = true) > JPA 조회하는 곳에서 성능을 최적화하게 도와줌 public List<Member> findMembers() { return memberRepository.findAll(); } //회원 단건 조회 public Member findOne(Long memberId) { return memberRepository.findOne(memberId); } }
- repository에도 @RequiredArgsConstructor 적용 가능
//변경 전 @Repository public class MemberRepository { @PersistenceContext private EntityManager em; } //변경 후 @Repository @RequiredArgsConstructor public class MemberRepository { private final EntityManager em; }
1) @PersistenceContext > @Autowired : 스프링부트에서 지원해주기 때문에 변경 가능
2) @Autowired > final 키워드 추가 + @RequiredArgsConstructor728x90'스프링&스프링부트' 카테고리의 다른 글
[스프링부트/웹 애플리케이션 개발]상품 엔티티 개발 (0) 2023.01.04 [스프링부트/웹 애플리케이션 개발]회원 기능 테스트 (0) 2023.01.04 [스프링부트/웹 애플리케이션 개발]애플리케이션 아키텍처 (1) 2023.01.04 [스프링부트/웹 애플리케이션 개발]엔티티 설계 주의 사항 (0) 2023.01.04 [스프링부트/웹 애플리케이션 개발]엔티티 클래스 개발 -2 (0) 2023.01.04