회원 도메인 개발

박민서·2023년 5월 10일
0

Jpa1

목록 보기
4/6

회원 리포지토리 개발

  • 리포지토리 패키지 생성
    MemberRepository 클래스 생성 후 @Repository 어노테이션을 붙여서 @Component 스캔으로 인해 자동으로 스프링 빈에 등록되어 관리됨
@PersistenceContext
private EntityManager em;

Jpa가 제공하는 표준 어노테이션 @PersistenceContext을 붙여주면 스프링이 엔티티매니저를 만들어 주입해준다.

public List findAll(){
return em.createQuery("select m from Member m ", Member.class)
.getResultList();
}

모든 멤버를 찾기 위해 em.createQuery라는 jpql을 작성해야 한다. jpql의 조회타입 "select m from Member m " , Member.class는 반환 타입

  • jpql과 sql의 차이점
    sql은 테이블을 대상으로 쿼리를 하는데 jpql은 엔티티 객체를 대상으로 쿼리를 한다.

    회원 서비스 개발

  • service 패키지를 만들고 MemberService 클래스 작성

  • 클래스 위에 @Service 어노테이션을 붙여주어야 스프링 빈으로 자동 등록됨

  • 영속성 컨텍스트에 키값과 value 값이 필요한데 PK이 값이 키 값이 된다.

  • JPA의 모든 데이터 변경이나 로직들은 가급적이면 트랜잭션 안에서 실행되어야 함
    @Transactional이 있어야 한다.

  • 클래스 레벨의 @Transactional을 쓰면 public 메서드들은 트랜잭션에 다 걸려간다.
    클래스 레벨에서 쓰지 않고 각각 메서드 위에 쓰게 되면 쓰기 전용 메서드에서는 @Transactional을 해주고 읽기 전용 메서드에서는 @Transactional(readonly=true)를 해주어야 한다. readonly = true를 하게 되면 데이터 변경이 안된다. 클래스 레벨에 위치해 있는 것 보다 메서드 위에 위치해 있는 것이 더 높은 우선순위를 가진다.

    @Autowired
    private MemberRepository memberRepository;

    스프링이 스프링 빈에 있는 memberRepository를 인잭션 해준다. 이 방식의 단점은 private 선언이라 접근할 수가 없다는 점 때문에 test코드를 작성할 때 불편하다. 해결책으로 setter 인잭션 방식을 사용 한다.

    @Autowired

    public void setMemberRepository(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
    }

    이 방식의 장점은 test 코드에서 내가 주입하고 싶은 가짜 memberRepositiory를 주입할 수 있다. 하지만 치명적은 단점으로 애플리케이션이 돌아가는 시점에 누군가 이 값을 바꿀 수 있다는 점이다. 그래서 생성자 주입 방식을 사용한다.

    @Autowired
    public MemberService(MemberRepository memberRepository){
    this.memberRepository=memberRepository;
    }

    스프링이 생성자에서 인잭션을 해준다. 중간에 memberRepository 값을 바꿀 수는 없다. test 코드 작성시에 내가 직접 주입을 해야 하기 때문에 의존하고 있다는 점을 놓치지않을 수 있다.
    하나의 생성자를 사용할 경우 @Autowired 어노테이션을 생략할 수 있다. 이제 필드는 변경할 일이 없기 때문에 final로 지정해주는게 좋다.

    private final MemberRepository memberRepository;

    Lombok의 @RequiredArgsConstructor 어노테이션을 사용하면 final이 있는 필드만 가지고 생성자를 만들어 주기 때문에 내가 직접 생성자를 적을 필요가 없어진다.
    이 기능을 MemberRepository에서도 사용할 수 있다.

    회원 기능 테스트

  • 단축키 ctrl + shift + t

  • Genegrate 전략에서는 영속성에서 insert문이 나가지 않는다.

  • @Transactional은 기본적으로 트랜잭션을 커밋하지 않고 롤백을 해버리기 때문에
    @Rollback(false)로 주면 됨 이러면 insert문이 나가는 것을 볼 수 있다.

  • @Rollback문을 쓰지 않는 rollback 상태에서 쿼리가 나가는걸 보고 싶다면 Entitymanager를 Autowired로 받아서 em.flush()

  • memory db 사용법
    test 폴더에 resources 디렉토리를 만들고 디렉토리 안에 application.yml을 복사해서 넣어주면 main에 있는 yml은 무시되고 test폴더에 있는 yml이 실행된다. h2database.com에서 jdbc:h2:mem:test를 복사해 yml url을 바꿔주면 된다.

profile
ㅎㅇㅌ

0개의 댓글