공지사항

- QueryProjection 사용
- QueryDSL을 통해 DTO로 바로 조회
This commit is contained in:
Klaus 2025-02-09 22:54:45 +09:00
parent 04f2ac6815
commit 8fb1247279
4 changed files with 39 additions and 32 deletions

View File

@ -6,11 +6,11 @@ import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerRespons
import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse
import kr.co.vividnext.sodalive.event.GetEventResponse import kr.co.vividnext.sodalive.event.GetEventResponse
import kr.co.vividnext.sodalive.explorer.GetExplorerSectionResponse import kr.co.vividnext.sodalive.explorer.GetExplorerSectionResponse
import kr.co.vividnext.sodalive.notice.NoticeTitleItem import kr.co.vividnext.sodalive.notice.NoticeItem
data class GetContentMainTabHomeResponse( data class GetContentMainTabHomeResponse(
val tabId: Long = 1, val tabId: Long = 1,
val latestNotice: NoticeTitleItem?, val latestNotice: NoticeItem?,
val bannerList: List<GetAudioContentBannerResponse>, val bannerList: List<GetAudioContentBannerResponse>,
val rankCreatorList: GetExplorerSectionResponse, val rankCreatorList: GetExplorerSectionResponse,
val rankSeriesList: List<GetSeriesListResponse.SeriesListItem>, val rankSeriesList: List<GetSeriesListResponse.SeriesListItem>,

View File

@ -7,14 +7,9 @@ data class GetNoticeResponse(
val noticeList: List<NoticeItem> val noticeList: List<NoticeItem>
) )
data class NoticeItem( data class NoticeItem @QueryProjection constructor(
val id: Long, val id: Long,
val title: String, val title: String,
val content: String, val content: String,
val date: String val date: String
) )
data class NoticeTitleItem @QueryProjection constructor(
val id: Long,
val title: String
)

View File

@ -5,8 +5,6 @@ import org.springframework.data.domain.Pageable
import org.springframework.data.repository.findByIdOrNull import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional import org.springframework.transaction.annotation.Transactional
import java.time.ZoneId
import java.time.format.DateTimeFormatter
@Service @Service
@Transactional(readOnly = true) @Transactional(readOnly = true)
@ -46,25 +44,11 @@ class ServiceNoticeService(private val repository: ServiceServiceNoticeRepositor
fun getNoticeList(pageable: Pageable, timezone: String): GetNoticeResponse { fun getNoticeList(pageable: Pageable, timezone: String): GetNoticeResponse {
val totalCount = repository.getNoticeTotalCount() val totalCount = repository.getNoticeTotalCount()
val noticeList = repository.getNoticeList(pageable) val noticeList = repository.getNoticeList(pageable)
.asSequence()
.map {
val createdAt = it.createdAt!!
.atZone(ZoneId.of("UTC"))
.withZoneSameInstant(ZoneId.of(timezone))
NoticeItem(
it.id!!,
it.title,
it.content,
createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
)
}
.toList()
return GetNoticeResponse(totalCount, noticeList) return GetNoticeResponse(totalCount, noticeList)
} }
fun getLatestNotice(): NoticeTitleItem? { fun getLatestNotice(): NoticeItem? {
return repository.getLatestNotice() return repository.getLatestNotice()
} }
} }

View File

@ -1,18 +1,22 @@
package kr.co.vividnext.sodalive.notice package kr.co.vividnext.sodalive.notice
import com.querydsl.core.types.dsl.DateTimePath
import com.querydsl.core.types.dsl.Expressions
import com.querydsl.core.types.dsl.StringTemplate
import com.querydsl.jpa.impl.JPAQueryFactory import com.querydsl.jpa.impl.JPAQueryFactory
import kr.co.vividnext.sodalive.notice.QServiceNotice.serviceNotice import kr.co.vividnext.sodalive.notice.QServiceNotice.serviceNotice
import org.springframework.data.domain.Pageable import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
import java.time.LocalDateTime
@Repository @Repository
interface ServiceServiceNoticeRepository : JpaRepository<ServiceNotice, Long>, ServiceNoticeQueryRepository interface ServiceServiceNoticeRepository : JpaRepository<ServiceNotice, Long>, ServiceNoticeQueryRepository
interface ServiceNoticeQueryRepository { interface ServiceNoticeQueryRepository {
fun getNoticeTotalCount(): Int fun getNoticeTotalCount(): Int
fun getNoticeList(pageable: Pageable): List<ServiceNotice> fun getNoticeList(pageable: Pageable): List<NoticeItem>
fun getLatestNotice(): NoticeTitleItem? fun getLatestNotice(): NoticeItem?
} }
@Repository @Repository
@ -26,9 +30,17 @@ class ServiceNoticeQueryRepositoryImpl(private val queryFactory: JPAQueryFactory
.size .size
} }
override fun getNoticeList(pageable: Pageable): List<ServiceNotice> { override fun getNoticeList(pageable: Pageable): List<NoticeItem> {
return queryFactory return queryFactory
.selectFrom(serviceNotice) .select(
QNoticeItem(
serviceNotice.id,
serviceNotice.title,
serviceNotice.content,
getFormattedDate(serviceNotice.createdAt)
)
)
.from(serviceNotice)
.where(serviceNotice.isActive.isTrue) .where(serviceNotice.isActive.isTrue)
.offset(pageable.offset) .offset(pageable.offset)
.limit(pageable.pageSize.toLong()) .limit(pageable.pageSize.toLong())
@ -36,12 +48,14 @@ class ServiceNoticeQueryRepositoryImpl(private val queryFactory: JPAQueryFactory
.fetch() .fetch()
} }
override fun getLatestNotice(): NoticeTitleItem? { override fun getLatestNotice(): NoticeItem? {
return queryFactory return queryFactory
.select( .select(
QNoticeTitleItem( QNoticeItem(
serviceNotice.id, serviceNotice.id,
serviceNotice.title serviceNotice.title,
serviceNotice.content,
getFormattedDate(serviceNotice.createdAt)
) )
) )
.from(serviceNotice) .from(serviceNotice)
@ -49,4 +63,18 @@ class ServiceNoticeQueryRepositoryImpl(private val queryFactory: JPAQueryFactory
.orderBy(serviceNotice.id.desc()) .orderBy(serviceNotice.id.desc())
.fetchFirst() .fetchFirst()
} }
private fun getFormattedDate(dateTimePath: DateTimePath<LocalDateTime>): StringTemplate {
return Expressions.stringTemplate(
"DATE_FORMAT({0}, {1})",
Expressions.dateTimeTemplate(
LocalDateTime::class.java,
"CONVERT_TZ({0},{1},{2})",
dateTimePath,
"UTC",
"Asia/Seoul"
),
"%Y-%m-%d"
)
}
} }