QueryDSL로 검색기능을 만들고, 게시물을 조회할 때 페이지 별로 필요한 갯수만큼을 DB에 요청이 가능하도록 페이징 기능도 구현했다.
QueryDSL검색기능
일단 시작전에 config와 gradle을 추가해주는작업을 해줘야한다.
QueryDSLConfig
@Configuration
public class QueryDslConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
build.gradle
// QueryDSL 적용을 위한 의존성
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
검색기능을 만들기전에 일단 build.gradle에 해당 의존성을 추가해주고
RepositoryQuery라는 interface와 클래스를 만들어줬다. QueryDSL을 사용하기 위해서다.
Class에는 @Repository 애너테이션이 붙어있어야하며
private final JPAQueryFactory jpaQueryFactory;
/* QueryDSL 사용하여 게시글 제목 중 keyword 검색 */
@Override
public List<Post> search(String keyword) {
QPost post = QPost.post;
var query = jpaQueryFactory.select(post)
.from(post)
.where(post.title.contains(keyword))
.fetch();
return query;
}
위에 Config에서 Bean등록해준 JpaQueryFactory를 주입받아 불러와서 사용한다.
where구문을 보면 contains를 사용하고 있는데 contains를 사용하면 입력한 키워드가 포함되어있는 문자열들을 모두 검색할 수 있다.
Pageable을 이용한 페이징기능
JPA에서 지원하는 pageable인터페이스를 이용해서 만들었는데, Pageable을 뜯어보면 내부에 페이지번호나, 몇개의 게시물이 들어갈지, 정렬은 어떻게 할지 등 많은 필드들이 존재하지만 난 기본적인 페이징 조회만 만들었으므로 size와 page만 이용했다.
해당 코드는 PostServiceImpl코드인데 매개변수를 Pageable로 바로 받아와도 가능하다. 해당 코드에서는 PageRequest.of를 이용해 만들어줬는데, 생성자 비슷한 것으로 보인다.
public List<Post> searchPageable(Pageable pageable) {
QPost post = QPost.post;
Long page = pageable.getOffset();
Integer size = pageable.getPageSize();
return jpaQueryFactory.selectFrom(post)
.offset(page)
.limit(size)
.fetch();
}
위 코드는 PostRepositoryQueryImpl코드로 QueryDSL의 빈 객체인 Q객체 QPost를 만들어주고,
getOffset은 pageable의 해당페이지의 번호를 나타낸다.
getPageSize는 pageable의 해당페이지 안에 들어갈 게시글의 숫자(크기)를 받아온다.
페이지에 맞는 갯수만큼의 post를 DB에 요청해서 리턴해준다.