실무에서는 커스텀 리포지토리를 구축하고나서 QueryDsl 을 사용한다는 이야기를 접했다.
조금이나마 흉내라도 내보고, 한자라도 쳐보기위해서 했던 작업을 기록한다.
첫번째로는 재정의할 메서드를 놓은 인터페이스를 정의한다.
public interface PostCustomRepository<T> {
List<Post> findMyPost();
}
두번째로는 인터페이스의 구현체를 만든다. @EnableJpaRepository 에 속성에 suffix 를 바꾸는 속성이 있으니 참고한다.
QueryFactory 를 이용해서 원하는 쿼리문을 직관적으로 짜낸다.
@Repository
@Transactional
public class PostCustomRepositoryImpl implements PostCustomRepository<Post> {
@Autowired
EntityManager entityManager;
@Override
public List<Post> findMyPost() {
JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
return queryFactory.select(post).from(post).where(post.id.gt(0)).fetch();
}
}
사용할 리포지토리는 두개의 인터페이스를 상속하는데 JpaRepository + CustomRepository 이다. 구현체는 각각 있어 등록됬으니 괜찮다.
public interface PostRepository extends JpaRepository<Post,Long>, PostCustomRepository<Post>, QuerydslPredicateExecutor<Post> {
}
이대로 테스트 코드를 쏘면 쿼리문이 잘나온다.
@SpringBootTest
@TestPropertySource(locations = "classpath:test.properties")
class PostRepositoryTest {
@Autowired
private PostRepository postRepository;
@Test
public void crud(){
postRepository.findMyPost();
};
}
심화과정, Pageable 과 같이 사용하기
일단 매개 값으로 Pageable 이 추가된다.
public interface PostCustomRepository<T> {
/**
*
* @return 0 보다 큰 포스트를 가져옴
*/
Page<Post> findMyPost(Pageable pageable);
}
이것을 정의하는데 OrderSpecifier 를 가져오는 메서드는 static 하므로 util 로 따로 지정해서 사용하는 것이 좋다고 한다.
- offset, limit 로 pageable 에 필요한 값을 가져오고 있음.
- orderBy 메서드에 OrderSpecifier 를 리턴하는 메서드를 정의해서 사용 중
- PageIml 을 사용하여 페이지 구성에 알맞은 결과를 리턴해 준다.
@Repository
@Transactional
public class PostCustomRepositoryImpl implements PostCustomRepository<Post> {
@Autowired
EntityManager entityManager;
@Override
public Page<Post> findMyPost(Pageable pageable) {
JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
QueryResults<Post> postQueryResults = queryFactory.select(post).from(post).where(post.id.gt(0))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(getSortColumn(Order.DESC,post,"registerDate"))
.fetchResults();
return new PageImpl<>(postQueryResults.getResults(),pageable,postQueryResults.getTotal());
}
private static OrderSpecifier<?> getSortColumn(Order order, Path<?> parent, String fieldName){
Path<Object> fieldPath = Expressions.path(Object.class,parent,fieldName);
return new OrderSpecifier(order,fieldPath);
}
}
이후 테스트 코드를 고쳐보면 이러하다.
@SpringBootTest
@TestPropertySource(locations = "classpath:test.properties")
class PostRepositoryTest {
@Autowired
private PostRepository postRepository;
@Test
public void crud(){
PageRequest request = PageRequest.of(0,10, Sort.by(Sort.Direction.DESC,"registerDate"));
postRepository.findMyPost(request);
};
}
참조: Stack OverFlow
'작업하면서 배우는 것들' 카테고리의 다른 글
SpringFox:Swagger3 사용 (0) | 2021.01.05 |
---|---|
QueryDsl Left Outer Join, Tuple, Projections (0) | 2020.12.27 |
JPA Projection FindAll (0) | 2020.12.24 |
Vue Router 와 Href 속성 (0) | 2020.12.24 |
Axios 사용 시 Zipkin 로그 트레이싱을 위한 wrapAxios (0) | 2020.12.23 |