당니의 개발자 스토리
회원 리포지토리 개발 본문
회원 리포지토리 개발
이번 시간에는 회원 도메인을 개발해 보겠습니다.

먼저 기본적으로 예전에 봤던 것처럼 회원을 등록하고 회원 목록을 조회하는 기능을 만들어 볼 거에요. 되게 단순하죠. 그런데 순서는 먼저 회원 엔티티 코드를 한번 다시 보고요. 그 다음에 회원 리포지토리 서비스, 이 두 가지를 개발한 다음에 그리고 회원 기능이 잘 동작하는지 테스트를 만들어서 돌려 보겠습니다.
이번 시간에는 먼저 회원 리포지토리를 개발해볼게요. 화면을 제외하고 핵심 도메인 비즈니스를 개발한다고 보시면 될 것 같아요.
그 전에 저희가 만들었던 회원 엔티티 코드를 보겠습니다.

자 보면은 멤버가 있고 단순하게 id, 그 다음에 회원명, 그 다음 주소, 그리고 일대다 양방향 맵핑으로 오더스를 가지고 있었죠. 이정도가 있는데 이거에 대한 리포지토리를 만들어 볼 거에요.

자 먼저 회원 리포지토리는 제가 패키지를 별도로 repository 라고 만들게요.

그런 다음 MemberRepository를 만들었습니다.

우선은 Spring를 사용하는 것이기 때문에 Spring에서 제공하는 repository annotation을 사용하면 얘가 이제 컴포넌트 스캔에 의해서 자동으로 Spring 빈으로 관리가 되게 되죠.

그 다음에 jpa를 어쨌든 저희가 사용하는 거기 때문에 jpa가 제공하는 표준 어노테이션인 @PersistenceContext 라는 걸 적어주면, 스프링이 entity manager를 만들어서 걔를 여기다가 주입해줍니다. injection 해주는 거죠. em이 있으면 저장 로직은 그냥 만들면 되죠.

이렇게 하면 회원을 em.persist(member); 해서 멤버를 딱 집어 넣으면 jpa가 member를 저장하는 로직이 되는 거구요.
그 다음에 조회하는 걸 만들어 볼게요.

이렇게 하면 em.find 해서 jpa가 제공하는 find method을 가지고 Member.class 하고 이 id 값을 넘기면, findOne이 해당 멤버를 찾아서 반환해주게 됩니다.
그 다음에 단 건 조회 말고 리스트 조회도 필요하단 말이에요.

저희가 화면을 봐서 알겠지만 회원 목록을 뿌렸던 거 기억나시죠? 그걸 하려면 리스트가 필요한데 findAll() 이라는 걸 만들어 볼게요.
자 이 findAll()은 전부 다 찾아야 되거든요. 이때는 em.createQuery라고 해가지고 jpql을 작성해야 됩니다. 첫 번째 인자가 jpql을 쓰고, 두번째가 반환 타입을 넣으면 되거든요. 그 다음에 getResultList() 라고 해주시면,

option + cmd + v로 보면 얘도 이제 Member를 리스트로 다 만들어주고요.

그 다음에 return result; 이렇게 해주면 되는데 이걸 합치는게 좋죠.

단축키 Inline 변수 해가지고 option + cmd + N 단축키 참고 하시구요.
자 이렇게 해서 조회된 결과를 반환해주면 됩니다.
그리고 참고로 jpql은 SQL이랑 조금 달라요. 뭐가 다르냐면 SQL 이랑 거의 똑같고 뭐 JOIN 이랑 문법이 약간씩 차이가 있는데 기능적으로는 거의 동일해요. 왜냐하면 jpql이 결국 SQL으로 번역이 돼야 되기 때문이에오. 근데 차이가 있어요.
SQL은 테이블을 대상으로 쿼리를 하는데, jpql은 entity 객체를 대상으로 쿼리를 한다고 보시면 돼요. Member에 대한 entity 객체의 alias를 m 으로 주고, entity 멤버를 조회해! 라고 해서 이렇게 문법이 나온 거구요.
jpql 에 대해서는 기본편에 잘 설명이 되어있으니까 그걸 참고해 주시면 될 것 같습니다.
이름으로 만약에 회원을 검색해야 되면,

return em.createquery 한 다음에 jpql을 짜는데 where 문이 들어가는 거죠. m.name = :name 이렇게 하면 이게 parameter를 binding하는 거거든요. 그 다음 조회 타입은 Member.class 이렇게 하시고,

setParameter("name", name)를 해주시면 돼요. 그 다음에 getResultList() 이렇게 하면 이 "name" parameter가 binding 되겠죠.
.setParameter를 사용하는 이유

jpql 문에 있는 :name에 대응하는 name을 넘겨주기 위해서다.
그렇게 해서 회원을 조회하는데 이름에 의해서 조회한다고 보시면 되겠습니다.

자 이렇게까지 해서 repository를 금방 만들었죠. 기능을 간단하게 설명드리자면,

기술적인 내용을 설명을 드리면 이 @Repository를 보고, 스프링이 스프링 빈으로 등록을 해주죠. 왜냐하면 이 @Repository를 까보면,

여기 보면 @Component라고 되어 있거든요. 그러면 컴포넌트 스캔의 대상이 돼서 Spring Boot 같은 경우에는 이제 기본적으로 동작 방식 자체가

여기에 있는 @SpringBootApplication 어노테이션이 있으면 자신이 속한 패키지랑 자신이 속한 패키지 하위에 있는 것을 다 Spring이 컴포넌트 스캔을 해요. 그래서 다 스프링 빈으로 자동 등록하거든요. 그런데 MemberRepository는

@SpringBootApplication이 있던 패키지보다 하위에 있기 때문에 컴포넌트 스캔의 대상이 되어서 스프링 빈으로 등록이 다 됩니다.

그리고 @PersistenceContext는 Spring이 어떤 기능까지 제공을 해주냐면 @PersistenceContext Annotation이 있으면 JPA의 Entity Manager를 Spring이 생성한 Entity Manager에 주입을 해줍니다.
이렇게 해서 Entity Manager를 주입받을 수 있고요. 원래 JPA를 순수하게 쓰면 Entity Manager 팩토리에서 Entity Manager를 꺼내서 써야 하는데요. 이젠 그럴 필요 없이 스프링이 다 해결해줍니다. 아주 편하죠?
혹시 만약에 entity manager factory를 직접 주입하고 싶다면,

@PersistenceUnit 이라고 있어요. 이걸 적어주시면, manager factory를 직접 주입받을 수도 있습니다. 이것은 거의 쓸리는 없겠죠.
여기까지 하면 repository 코드가 완성이 됩니다. 기본적인 엔티티 매니저를 사용하는 것을 말씀드리면,

persist 하면 일단은 영속성 컨텍스트에 member 엔티티를 넣죠. 그럼 나중에 트랜잭션이 commit 되는 시점에 db에 반영이 되겠죠. db에 insert 쿼리가 날아가는 겁니다.

그 다음 findeOne은 jpa의 find method을 사용하는데 단 건 조회예요. 첫번째 Type이고 두번째 PK, 즉 Primary Key를 넣어주시면 됩니다.

그 다음에 findAll은 JPQL을 썼죠. Create Query 해서 JPQL을 썼고 이 JPQL에 대한 문법은 SQL과 거의 똑같은데 이제 이 froom의 대상이 테이블이 아니라, Entity가 된다고 보시면 됩니다.
jpql에 대해서는 제 책이나 아니면 jpa의 기본편 강의를 참고해 주시면 될 것 같아요.

그리고 findByName은 Parameter Binding을 해서 특정 이름에 의한 회원만 잡는 것을 만들어 봤습니다.
자 이렇게 했고 다음 시간에는 회원 서비스를 한번 개발해 보겠습니다.
'스프링 > 실전! 스프링 부트와 JPA 활용1' 카테고리의 다른 글
| 회원 기능 테스트 (0) | 2024.04.27 |
|---|---|
| 회원 서비스 개발 (0) | 2024.04.24 |
| 애플리케이션 아키텍처 (0) | 2024.04.24 |
| 구현 요구사항 (0) | 2024.04.24 |
| 엔티티 설계시 주의점 (0) | 2024.04.24 |