[Spring Data JPA] 사용자 정의 리포지토리와 확장 기능
Spring Data JPA 가 제공하는 기능을 사용하면 개발이 생산성이 증가하지만, 상황에 따라 특정 기능은 Spring Data JPA가 제공하는 방법 대신 다른 방법을 사용해야 하는 경우가 생긴다. (JPA를 직접 사용한다던가, MyBatis를 사용한다던가...)
이럴 때는 어떻게 해야 할까?
Spring Data JPA는 이런 경우 Custom Repository를 사용할 수 있도록 한다.
사용자가 직접 인터페이스를 만들고, 필요한 기능을 원하는 방법으로 구현한 후 Spring Data JPA와 합치는 방식으로 문제를 해결한다.
MemberRepositoryCustom에 구현하려는 기능을 선언하고, MemberRepositoryImpl에서 기능을 구현한다. (둘 다 인터페이스이다)
이후 JpaRepository를 상속받는 MemberRepository 인터페이스가 MemberRepositoryImpl 인터페이스를 상속받도록 설정해주면 된다.
이 때 지켜야 할 규칙이 있는데, 커스텀 리포지토리를 구현하는 인터페이스의 이름은
JpaRepository를 상속받는 인터페이스의 이름 + Impl
또는
커스텀 리포지토리의 이름 + Impl
로 설정해야 한다. (Spring Data JPA가 인식하기 위함)
간단한 기능들은 Spring Data JPA가 제공하는 기능을 사용하고, 복잡한 기능은 따로 인터페이스로 만들고 QueryDsl 기술을 사용해서 구현하는 방식으로 사용하자.
JPA로 커뮤니티 게시판을 만든다고 생각해보자.
엔티티를 수정하거나 생성할 때 수정한 사람 및 시간을 추적하기 위해 엔티티는 해당 정보를 포함한다.
데이터베이스 테이블에는 당연히 하나씩 들어가는게 맞지만, 엔티티는 객체이기 때문에 멤버 변수를 하나씩 추가하는 방법 말고도 더 스마트하게 처리할 수 있다.
JPA만 사용하는 경우 BaseEntity 클래스를 따로 분리해 추적을 위한 정보를 포함시킨 후 다른 클래스에 상속하는 방식으로 처리하지만, Spring Data JPA는 훨씬 더 효과적으로 처리하는 방법을 제공한다.
먼저 @EnableJpaAuditing 애너테이션을 스프링 부트 설정 클래스에 적용하고 시작하자.
이후 추적에 필요한 데이터들을 BaseEntity로 분리한다.
@EntityListeners 애너테이션으로 Spring Data JPA가 해당 클래스를 알아볼 수 있도록 설정하자.
등록일과 수정일은 해당하는 애너테이션이 있어 바로 가져다가 사용하면 된다.
등록자와 수정자는 애너테이션으로 설정한 후 한 가지 작업이 더 필요하다.
등록자와 수정자를 처리해주는 AuditorAware를 Bean으로 등록해 엔티티가 등록되거나 수정될 때 변경될 수 있도록 설정한다.
등록될 때 수정 관련 값도 함께 설정해주자. null로 설정되면 나중에 힘들어진다.
Web확장 기능 중 유용한 기능이 있다.
컨트롤러에 findMember 함수를 정의했다.
원래대로라면 long타입의 id를 매개변수로 받아야 하지만, Member를 받는다.
도메인 클래스 컨버터가 중간에서 회원 엔티티 객체를 반환하도록 도와주고, 바로 Member를 조회할 수 있게 된다.
내부적으로는 원래와 마찬가지로 Repository를 통해 엔티티를 찾는다.
진짜 유용한 기능은 두 번째 함수에서 확인할 수 있다.
list 메서드의 매개변수로 Pageable 객체를 받는다.
( /members?page=0&size=3&sort=id,desc&sort=username,desc ) 왼쪽과 같은 URL이 입력됐을 경우 list 메서드가 받아서 처리하게 되고, URL의 내용대로 페이징 처리한 후 데이터를 보여준다.
URL이 지저분해지는걸 방지하려면 application.yml 파일에 기본값을 설정하거나
@PageableDefault 애너테이션에 기본값을 설정해 주면 된다.
페이징 대상이 되는 정보가 둘 이상이면 @Qualifier 애너테이션을 사용해서 처리할 수 있고, 반환값이 Page인 경우 TotalCount 쿼리가 나가니 성능 관련 이슈가 발생하면 이 부분을 처리해주자.
당연히 엔티티를 외부에 바로 노출하는건 위험하니 DTO로 변환하는 등 다른 방법을 사용하는 편이 합리적이다.
'Spring > Spring Data JPA' 카테고리의 다른 글
[Spring Data JPA] 내부 동작 원리 (0) | 2023.01.03 |
---|---|
[Spring Data JPA] 벌크 연산과 EntityGraph (0) | 2023.01.02 |
[Spring Data JPA] 쿼리 메서드와 페이징 (0) | 2023.01.02 |
[Spring Data JPA] 공통 인터페이스 (0) | 2023.01.02 |
댓글
이 글 공유하기
다른 글
-
[Spring Data JPA] 내부 동작 원리
[Spring Data JPA] 내부 동작 원리
2023.01.03 -
[Spring Data JPA] 벌크 연산과 EntityGraph
[Spring Data JPA] 벌크 연산과 EntityGraph
2023.01.02 -
[Spring Data JPA] 쿼리 메서드와 페이징
[Spring Data JPA] 쿼리 메서드와 페이징
2023.01.02 -
[Spring Data JPA] 공통 인터페이스
[Spring Data JPA] 공통 인터페이스
2023.01.02