공지사항
- QueryProjection 사용 - QueryDSL을 통해 DTO로 바로 조회
This commit is contained in:
		| @@ -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>, | ||||||
|   | |||||||
| @@ -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 |  | ||||||
| ) |  | ||||||
|   | |||||||
| @@ -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() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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" | ||||||
|  |         ) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user