-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* docs: flyway V1.00.0.15 배포 * refactor: article_main_card 테이블에서 content 삭제 * refactor: LocalDateTime에 대한 Json serialize 설정 추가 * feat: 아티클 목록 조회에서 카테고리 코드 파람 추가 * test: 아티클 목록 조회 API 카테고리 코드 추가 반영 * feat: 아티클 카테고리 조회 API 추가 * fix: PK 수정 * fix: 아티클 카테고리 조회시 displayname을 보내도록 수정 * feat: 아티클 목록 조회 API 1차 구현(step1: 조회수 및 카테고리 기반 정렬 상위 10개 조회) * feat: 아티클 최초 생성시 조회수 테이블 0으로 초기화하도록 변경 * feat: isLast에 대한 로직 처리를 UC로 이동 * test: article 카테고리 조회 API 테스트 구현 * fix: ARTICLE_MAIN_CARD 컬럼 수정 * fix: ARTICLE_MAIN_CARD 테이블 컬럼 타입 변경 * fix: ARTICLE_MAIN_CARD 테이블 컬럼 타입 변경 (description 컬럼 json으로 유지) * feat: 아티클 목록 조회, 저장 SQL 추가 * feat: 아티클 컨텐츠 조회 SQL 생성 * feat: 아티클 Main card DB 접근의 경우 한정 구현 * chore: TODO 주석 추가 * fix: selectArticlesOrderByViewsQuery 문법 수정 * fix: article main card 뷰 조합 SQL 수정(테이블명 수정) * fix: workbooks 삭제 * fix: json query * fix: ARTICLE_MAIN_CARD 테이블에서 workbooks 컬럼 삭제 * fix: 트랜잭션 readOnly 옵션 일시 삭제(insert 쿼리) * fix: 워크북 응답 삭제 * feat: 조회수가 같을 경우 최신 아티클이 우선순위가 높도록 수정 * test: [GET] /api/v1/articles/categories 테스트 수정 * fix: 아티클이 이미 테이블에 있느 경우에도 컨텐츠 조회되도록 변경 * refactor: 쿼리 수정 * refactor: 아티클 카테고리 조회 API 수정 (DTO 삭제) * fix: row rank 쿼리 문법 수정 * feat: record class <-> 쿼리 수행 결과 변환 매퍼 ArticleMainCardMapper 구현 * feat: ARTICLE_MAIN_CARD 테이블 workbooks 컬럼 추가(아티클이 포함된 워크북 정보 json) * feat:JDBC URL 옵션 추가 - allowMultiQueries=true * feat: record 필드(workbooks) 추가 및 워크북 json mapper 적용 * feat: 아티클 목록 조회 응답 바디 수정 (workbooks[] 추가) * test: data.articles[].workbooks 응답 바디 추가 테스트 코드 수정 * fix: selectArticlesOrderByViewsQuery 문법 일부 수정 * test: Duplicate entry '[email protected]' for key 'member.email' 에러 해결 * refacotr: kotlin logger로 변경 * test: insertMember 메소드로 트랜잭션 분리 * test: #e3dd2b9 원복
- Loading branch information
Showing
31 changed files
with
584 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
api-repo/src/main/kotlin/com/few/api/repo/dao/article/ArticleMainCardDao.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package com.few.api.repo.dao.article | ||
|
||
import jooq.jooq_dsl.tables.ArticleMst.ARTICLE_MST | ||
import jooq.jooq_dsl.tables.Member.MEMBER | ||
import com.few.api.repo.dao.article.record.ArticleMainCardRecord | ||
import com.few.api.repo.dao.article.support.CommonJsonMapper | ||
import com.few.api.repo.dao.article.support.ArticleMainCardMapper | ||
import jooq.jooq_dsl.tables.ArticleMainCard.ARTICLE_MAIN_CARD | ||
import jooq.jooq_dsl.tables.MappingWorkbookArticle.MAPPING_WORKBOOK_ARTICLE | ||
import jooq.jooq_dsl.tables.Workbook.WORKBOOK | ||
import org.jooq.* | ||
import org.jooq.impl.DSL.* | ||
import org.springframework.stereotype.Repository | ||
|
||
@Repository | ||
class ArticleMainCardDao( | ||
private val dslContext: DSLContext, | ||
private val commonJsonMapper: CommonJsonMapper, | ||
private val articleMainCardMapper: ArticleMainCardMapper, | ||
) { | ||
|
||
fun selectArticleMainCardsRecord(articleIds: Set<Long>): Set<ArticleMainCardRecord> { | ||
return selectArticleMainCardsRecordQuery(articleIds) | ||
.fetch(articleMainCardMapper) | ||
.toSet() | ||
} | ||
|
||
private fun selectArticleMainCardsRecordQuery(articleIds: Set<Long>) = dslContext.select( | ||
ARTICLE_MAIN_CARD.ID.`as`(ArticleMainCardRecord::articleId.name), | ||
ARTICLE_MAIN_CARD.TITLE.`as`(ArticleMainCardRecord::articleTitle.name), | ||
ARTICLE_MAIN_CARD.MAIN_IMAGE_URL.`as`(ArticleMainCardRecord::mainImageUrl.name), | ||
ARTICLE_MAIN_CARD.CATEGORY_CD.`as`(ArticleMainCardRecord::categoryCd.name), | ||
ARTICLE_MAIN_CARD.CREATED_AT.`as`(ArticleMainCardRecord::createdAt.name), | ||
ARTICLE_MAIN_CARD.WRITER_ID.`as`(ArticleMainCardRecord::writerId.name), | ||
ARTICLE_MAIN_CARD.WRITER_EMAIL.`as`(ArticleMainCardRecord::writerEmail.name), | ||
jsonGetAttributeAsText( | ||
ARTICLE_MAIN_CARD.WRITER_DESCRIPTION, | ||
"name" | ||
).`as`(ArticleMainCardRecord::writerName.name), | ||
jsonGetAttribute(ARTICLE_MAIN_CARD.WRITER_DESCRIPTION, "url").`as`(ArticleMainCardRecord::writerImgUrl.name), | ||
ARTICLE_MAIN_CARD.WORKBOOKS.`as`(ArticleMainCardRecord::workbooks.name) | ||
).from(ARTICLE_MAIN_CARD) | ||
.where(ARTICLE_MAIN_CARD.ID.`in`(articleIds)) | ||
.query | ||
|
||
fun selectByArticleMstAndMemberAndMappingWorkbookArticleAndWorkbook(articleIds: Set<Long>): Set<ArticleMainCardRecord> { | ||
return selectByArticleMstAndMemberAndMappingWorkbookArticleAndWorkbookQuery(articleIds) | ||
.fetch(articleMainCardMapper) | ||
.toSet() | ||
} | ||
|
||
private fun selectByArticleMstAndMemberAndMappingWorkbookArticleAndWorkbookQuery(articleIds: Set<Long>) = | ||
dslContext.select( | ||
ARTICLE_MST.ID.`as`(ArticleMainCardRecord::articleId.name), | ||
ARTICLE_MST.TITLE.`as`(ArticleMainCardRecord::articleTitle.name), | ||
ARTICLE_MST.MAIN_IMAGE_URL.`as`(ArticleMainCardRecord::mainImageUrl.name), | ||
ARTICLE_MST.CATEGORY_CD.`as`(ArticleMainCardRecord::categoryCd.name), | ||
ARTICLE_MST.CREATED_AT.`as`(ArticleMainCardRecord::createdAt.name), | ||
MEMBER.ID.`as`(ArticleMainCardRecord::writerId.name), | ||
MEMBER.EMAIL.`as`(ArticleMainCardRecord::writerEmail.name), | ||
jsonGetAttributeAsText(MEMBER.DESCRIPTION, "name").`as`(ArticleMainCardRecord::writerName.name), | ||
jsonGetAttribute(MEMBER.DESCRIPTION, "url").`as`(ArticleMainCardRecord::writerImgUrl.name), | ||
jsonArrayAgg( | ||
jsonObject( | ||
key("id").value(WORKBOOK.ID), | ||
key("title").value(WORKBOOK.TITLE) | ||
) | ||
).`as`(ArticleMainCardRecord::workbooks.name) | ||
) | ||
.from(ARTICLE_MST) | ||
.join(MEMBER).on(ARTICLE_MST.MEMBER_ID.eq(MEMBER.ID)).and(ARTICLE_MST.DELETED_AT.isNull) | ||
.and(MEMBER.DELETED_AT.isNull) | ||
.leftJoin(MAPPING_WORKBOOK_ARTICLE).on(ARTICLE_MST.ID.eq(MAPPING_WORKBOOK_ARTICLE.ARTICLE_ID)).and(MAPPING_WORKBOOK_ARTICLE.DELETED_AT.isNull) | ||
.leftJoin(WORKBOOK).on(MAPPING_WORKBOOK_ARTICLE.WORKBOOK_ID.eq(WORKBOOK.ID)).and(WORKBOOK.DELETED_AT.isNull) | ||
.where(ARTICLE_MST.ID.`in`(articleIds)) | ||
.groupBy(ARTICLE_MST.ID) | ||
.query | ||
|
||
fun insertArticleMainCardsBulk(commands: Set<ArticleMainCardRecord>) { | ||
dslContext.batch( | ||
commands.map { command -> insertArticleMainCardsBulkQuery(command) } | ||
).execute() | ||
} | ||
|
||
fun insertArticleMainCardsBulkQuery(command: ArticleMainCardRecord) = | ||
dslContext.insertInto( | ||
ARTICLE_MAIN_CARD, | ||
ARTICLE_MAIN_CARD.ID, | ||
ARTICLE_MAIN_CARD.TITLE, | ||
ARTICLE_MAIN_CARD.MAIN_IMAGE_URL, | ||
ARTICLE_MAIN_CARD.CATEGORY_CD, | ||
ARTICLE_MAIN_CARD.CREATED_AT, | ||
ARTICLE_MAIN_CARD.WRITER_ID, | ||
ARTICLE_MAIN_CARD.WRITER_EMAIL, | ||
ARTICLE_MAIN_CARD.WRITER_DESCRIPTION, | ||
ARTICLE_MAIN_CARD.WORKBOOKS | ||
).values( | ||
command.articleId, | ||
command.articleTitle, | ||
command.mainImageUrl.toString(), | ||
command.categoryCd, | ||
command.createdAt, | ||
command.writerId, | ||
command.writerEmail, | ||
JSON.valueOf( | ||
commonJsonMapper.toJsonStr( | ||
mapOf( | ||
"name" to command.writerName, | ||
"url" to command.writerImgUrl | ||
) | ||
) | ||
), | ||
JSON.valueOf(articleMainCardMapper.toJsonStr(command.workbooks)) | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
...epo/src/main/kotlin/com/few/api/repo/dao/article/query/SelectArticlesOrderByViewsQuery.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.few.api.repo.dao.article.query | ||
|
||
import com.few.data.common.code.CategoryType | ||
|
||
data class SelectArticlesOrderByViewsQuery( | ||
val offset: Long, | ||
val category: CategoryType?, | ||
) |
5 changes: 5 additions & 0 deletions
5
api-repo/src/main/kotlin/com/few/api/repo/dao/article/query/SelectRankByViewsQuery.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.few.api.repo.dao.article.query | ||
|
||
data class SelectRankByViewsQuery( | ||
val articleId: Long, | ||
) |
32 changes: 32 additions & 0 deletions
32
api-repo/src/main/kotlin/com/few/api/repo/dao/article/record/ArticleMainCardRecord.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.few.api.repo.dao.article.record | ||
|
||
import java.net.URL | ||
import java.time.LocalDateTime | ||
|
||
data class ArticleMainCardRecord( | ||
val articleId: Long, | ||
val articleTitle: String, | ||
val mainImageUrl: URL, | ||
val categoryCd: Byte, | ||
val createdAt: LocalDateTime, | ||
val writerId: Long, | ||
val writerEmail: String, | ||
val writerName: String, | ||
val writerImgUrl: URL, | ||
val workbooks: List<WorkbookRecord> = emptyList(), | ||
) { | ||
var content: String = "" | ||
set(value) { | ||
field = value | ||
} | ||
|
||
var views: Long = 0L | ||
set(value) { | ||
field = value | ||
} | ||
} | ||
|
||
data class WorkbookRecord( | ||
val id: Long?, | ||
val title: String?, | ||
) |
6 changes: 6 additions & 0 deletions
6
api-repo/src/main/kotlin/com/few/api/repo/dao/article/record/SelectArticleContentsRecord.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.few.api.repo.dao.article.record | ||
|
||
data class SelectArticleContentsRecord( | ||
val articleId: Long, | ||
val content: String, | ||
) |
6 changes: 6 additions & 0 deletions
6
api-repo/src/main/kotlin/com/few/api/repo/dao/article/record/SelectArticleViewsRecord.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.few.api.repo.dao.article.record | ||
|
||
data class SelectArticleViewsRecord( | ||
val articleId: Long, | ||
val views: Long, | ||
) |
36 changes: 36 additions & 0 deletions
36
api-repo/src/main/kotlin/com/few/api/repo/dao/article/support/ArticleMainCardMapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.few.api.repo.dao.article.support | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.fasterxml.jackson.module.kotlin.readValue | ||
import com.few.api.repo.dao.article.record.ArticleMainCardRecord | ||
import com.few.api.repo.dao.article.record.WorkbookRecord | ||
import org.jooq.JSON | ||
import org.jooq.RecordMapper | ||
import org.jooq.Record | ||
import org.springframework.stereotype.Component | ||
import java.net.URL | ||
import java.time.LocalDateTime | ||
|
||
@Component | ||
class ArticleMainCardMapper( | ||
private val objectMapper: ObjectMapper, | ||
) : RecordMapper<Record, ArticleMainCardRecord> { | ||
override fun map(record: Record): ArticleMainCardRecord { | ||
val workbooksJsonArrayStr: String = record.get(ArticleMainCardRecord::workbooks.name, JSON::class.java).data() | ||
|
||
return ArticleMainCardRecord( | ||
articleId = record.get(ArticleMainCardRecord::articleId.name, Long::class.java), | ||
articleTitle = record.get(ArticleMainCardRecord::articleTitle.name, String::class.java), | ||
mainImageUrl = record.get(ArticleMainCardRecord::mainImageUrl.name, URL::class.java), | ||
categoryCd = record.get(ArticleMainCardRecord::categoryCd.name, Byte::class.java), | ||
createdAt = record.get(ArticleMainCardRecord::createdAt.name, LocalDateTime::class.java), | ||
writerId = record.get(ArticleMainCardRecord::writerId.name, Long::class.java), | ||
writerEmail = record.get(ArticleMainCardRecord::writerEmail.name, String::class.java), | ||
writerName = record.get(ArticleMainCardRecord::writerName.name, String::class.java), | ||
writerImgUrl = record.get(ArticleMainCardRecord::writerImgUrl.name, URL::class.java), | ||
workbooks = objectMapper.readValue<List<WorkbookRecord>>(workbooksJsonArrayStr) | ||
) | ||
} | ||
|
||
fun toJsonStr(workbooks: List<WorkbookRecord>) = objectMapper.writeValueAsString(workbooks) | ||
} |
13 changes: 13 additions & 0 deletions
13
api-repo/src/main/kotlin/com/few/api/repo/dao/article/support/CommonJsonMapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.few.api.repo.dao.article.support | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class CommonJsonMapper( // TODO: common 성 패키지 위치로 이동 | ||
private val objectMapper: ObjectMapper, | ||
) { | ||
fun toJsonStr(map: Map<String, Any>): String { | ||
return objectMapper.writeValueAsString(map) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.