Whiteship Spring JPA, Custom Repository
2020-12-12
기본으로 제공되는 쿼리 메소드로 해결이 되지 않는 경우,
- 직접 구현하거나
- 기본으로 제공되는 기능을 덮어 쓸 수도 있다.
- Repository class 에 JpaRepository 를 상속받고 추가로 직접 구현한 implementation class 를 상속받는 방식.
- implementation class 에 기본적인 naming convention 이 존재한다. 기본 postfix
Impl
(ex:내가만든클래스명Imple
) - 기본 naming convention 은
@EnableJpaRepositories(repositoryImplementationPostfix = "PostfixWhatIWant")
로 변경가능
예제
먼저 요딴식으로 interface 를 만들고, 직접 구현할 또는 덮어 쓸 기능을 추가한다.
public interface MyCustomPostRepository {
List<Post> findMyPost();
}
그리고 직접 구현한다. 구현 class 의 postfix 는 Impl
이다.
postfix 를 바꾸려면 main class 에 @EnableJpaRepositories(repositoryImplementationPostfix = "MyPostFix")
로 변경해야함
String repositoryImplementationPostfix() default "Impl";
기본값이 Impl 임.
@Repository
@Transactional
public class MyCustomPostRepositoryImpl implements MyCustomPostRepository {
Logger logger = LoggerFactory.getLogger(MyCustomPostRepository.class);
@Autowired
EntityManager entityManager;
@Override
public List<Post> findMyPost() {
logger.debug("called!");
return entityManager.createQuery("select p from Post as p", Post.class).getResultList();
}
}
그리고 JpaRepository 와 만들어둔 interface 를 둘 다 상속받은 Repository 를 만든다.
public interface PostRepository extends JpaRepository<Post, Long>, MyCustomPostRepository {
}
그리고 사용하면 끝.
어느 글에 보면 JpaRepository 의 기본 구현체에서 사용하는 delete 는 cascade 나 entity manager 의 1차 캐싱 등 여러 작업을 하기 때문에, 비효율적으로 보일 수 있지만 그렇지 않다.
아무튼 내가 원하는 방식으로 함수를 덮어 쓰고싶다고하면, interface 에 같은 타입의 함수를 넣고 구현하면 된다.