QDSL 적용, 기존 JPQL QDSL로 변경, 동적 쿼리 작성

This commit is contained in:
jinia91
2022-04-01 22:51:55 +09:00
parent 6912ca24ff
commit 7a53589937
7 changed files with 75 additions and 54 deletions

View File

@@ -2,7 +2,7 @@ plugins {
id 'org.springframework.boot' version '2.5.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id "org.jetbrains.kotlin.jvm" version "1.5.0-RC"
// id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
id "com.github.node-gradle.node" version "3.1.0"
id 'java'
@@ -44,7 +44,7 @@ dependencies {
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.9'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'
implementation 'io.sentry:sentry-spring-boot-starter:5.6.1'
// implementation 'com.querydsl:querydsl-jpa'
implementation 'com.querydsl:querydsl-jpa'
implementation 'com.github.node-gradle:gradle-node-plugin:3.1.0'
implementation group: 'org.modelmapper', name: 'modelmapper', version: '2.4.4'
implementation group: 'org.kohsuke', name: 'github-api', version: '1.133'
@@ -80,22 +80,21 @@ test {
useJUnitPlatform()
}
// 쿼리DSL 설정
//def querydslDir = "$buildDir/generated/querydsl"
//
//querydsl {
// jpa = true
// querydslSourcesDir = querydslDir
//}
//sourceSets {
// main.java.srcDir querydslDir
//}
//configurations {
// querydsl.extendsFrom compileClasspath
//}
//compileQuerydsl {
// options.annotationProcessorPath = configurations.querydsl
//}
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets {
main.java.srcDir querydslDir
}
configurations {
querydsl.extendsFrom compileClasspath
}
compileQuerydsl {
options.annotationProcessorPath = configurations.querydsl
}
compileTestKotlin {

View File

@@ -1,7 +1,6 @@
package myblog.blog.article.adapter.outgoing.persistence;
import lombok.RequiredArgsConstructor;
import myblog.blog.article.application.port.outgoing.ArticleBackupRepositoryPort;
import myblog.blog.article.application.port.outgoing.ArticleRepositoryPort;
import myblog.blog.article.domain.Article;
import myblog.blog.category.domain.Category;
@@ -19,6 +18,7 @@ public class ArticleRepositoryAdapter implements ArticleRepositoryPort {
private final JpaArticleRepository jpaArticleRepository;
private final MybatisArticleRepository mybatisArticleRepository;
private final QdslArticleRepository qdslArticleRepository;
@Override
public List<Article> findTop6ByOrderByHitDesc() {
@@ -36,13 +36,8 @@ public class ArticleRepositoryAdapter implements ArticleRepositoryPort {
}
@Override
public List<Article> findByOrderByIdDescWithList(Pageable pageable) {
return jpaArticleRepository.findByOrderByIdDescWithList(pageable);
}
@Override
public List<Article> findByOrderByIdDesc(Long articleId, Pageable pageable) {
return jpaArticleRepository.findByOrderByIdDesc(articleId, pageable);
public List<Article> findByOrderByIdDesc(Long articleId, int size) {
return qdslArticleRepository.findByOrderByIdDesc(articleId, size);
}
@Override

View File

@@ -28,25 +28,6 @@ public interface JpaArticleRepository extends JpaRepository<Article, Long> {
*/
Slice<Article> findByOrderByIdDesc(Pageable pageable);
/*
- 커서페이징으로 최신 게시물 가져오기
- 첫번째 페이지용 쿼리
*/
@Query("select a " +
"from Article a " +
"order by a.id desc ")
List<Article> findByOrderByIdDescWithList(Pageable pageable);
/*
- 커서페이징으로 최신 게시물 가져오기
- 커서 적용
*/
@Query("select a " +
"from Article a " +
"where a.id < :articleId " +
"order by a.id desc")
List<Article> findByOrderByIdDesc(@Param("articleId") Long articleId,Pageable pageable);
/*
- 카테고리별(하위 카테고리) 페이징 처리해서 최신게시물순으로 Slice 가져오기
*/

View File

@@ -0,0 +1,31 @@
package myblog.blog.article.adapter.outgoing.persistence;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import myblog.blog.article.domain.Article;
import org.springframework.stereotype.Repository;
import java.util.List;
import static myblog.blog.article.domain.QArticle.article;
@Repository
@RequiredArgsConstructor
public class QdslArticleRepository {
private final JPAQueryFactory queryFactory;
List<Article> findByOrderByIdDesc(Long articleId, int size){
return queryFactory
.selectFrom(article)
.where(cursorLt(articleId))
.orderBy(article.id.desc())
.limit(size)
.fetch();
}
private Predicate cursorLt(Long articleId) {
return articleId == 0L ? null : article.id.lt(articleId);
}
}

View File

@@ -49,17 +49,13 @@ public class ArticleQueries implements ArticleQueriesUseCase {
/*
- 메인화면 위한 최신 아티클 커서 페이징해서 가져오기
- 레이아웃 렌더링 성능 향상을 위해 캐싱작업
카테고리 변경 / 아티클 변경이 존재할경우 레이아웃 캐시 초기화
카테고리 변경 / 아티클 변경이 존재할경우 레이아웃 캐시 초기화 정책
*/
@Override
@Cacheable(value = "layoutRecentArticleCaching", key = "#lastArticleId")
public List<ArticleResponseForCardBox> getRecentArticles(Long lastArticleId) {
List<Article> articles = lastArticleId.equals(0L) ?
articleRepositoryPort
.findByOrderByIdDescWithList(PageRequest.of(0, 5))
:
articleRepositoryPort
.findByOrderByIdDesc(lastArticleId, PageRequest.of(0, 5));
List<Article> articles = articleRepositoryPort
.findByOrderByIdDesc(lastArticleId, 5);
return articles
.stream()
.map(article -> MapperUtils.getModelMapper().map(article, ArticleResponseForCardBox.class))

View File

@@ -13,8 +13,7 @@ public interface ArticleRepositoryPort {
List<Article> findTop6ByOrderByHitDesc();
List<Article> findTop6ByCategoryOrderByIdDesc(Category category);
Slice<Article> findByOrderByIdDesc(Pageable pageable);
List<Article> findByOrderByIdDescWithList(Pageable pageable);
List<Article> findByOrderByIdDesc(Long articleId, Pageable pageable);
List<Article> findByOrderByIdDesc(Long articleId, int size);
Slice<Article> findBySubCategoryOrderByIdDesc(Pageable pageable, String category);
Slice<Article> findBySuperCategoryOrderByIdDesc(Pageable pageable, String category);
Article findArticleByIdFetchCategoryAndTags(Long articleId);

View File

@@ -0,0 +1,20 @@
package myblog.blog.infra.config;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Configuration
public class DBConfig {
@PersistenceContext
private EntityManager em;
@Bean
public JPAQueryFactory jpaQueryFactoryConfig(){
return new JPAQueryFactory(em);
}
}