Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb87c250b6 | ||
|
|
81a6f9d86b | ||
|
|
ad70bb1f2e | ||
|
|
2f2adebbf2 | ||
|
|
31b6c85b77 | ||
|
|
23cff9d75f | ||
|
|
15e952893b | ||
|
|
1c855f60b0 | ||
|
|
4983029a8f | ||
|
|
b2561d6608 | ||
|
|
c72f7be010 | ||
|
|
273e3cbf62 |
65
README.md
Normal file
65
README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# demo-hexagonal
|
||||
|
||||
### Hexagonal Architecture 구조로 만든 코프링 웹 애플리케이션<br>
|
||||
|
||||
Kotlin + Spring Boot 2 + Spring MVC + Spring Data JPA
|
||||
|
||||
<p>
|
||||
<img src="https://img.shields.io/static/v1?label=OpenJDK&message=17.0.2&color=007396&logo=openjdk" alt="OpenJDK">
|
||||
<img src="https://img.shields.io/static/v1?label=Kotlin&message=1.6.21&color=7F52FF&logo=kotlin&logoColor=fff" alt="Kotlin">
|
||||
<img src="https://img.shields.io/static/v1?label=Spring%20Boot&message=2.7.3&color=6DB33F&logo=springboot&logoColor=fff" alt="Spring Boot">
|
||||
<img src="https://img.shields.io/static/v1?label=Gradle&message=7.5.1&color=02303A&logo=Gradle&logoColor=fff" alt="Gradle">
|
||||
<img src="https://img.shields.io/static/v1?label=MariaDB&message=10.8.3&color=003545&logo=MariaDB" alt="MariaDB">
|
||||
<img src="https://img.shields.io/static/v1?label=Swagger&message=3.0.3&color=85EA2D&logo=swagger&logoColor=fff" alt="Swagger 3">
|
||||
</p>
|
||||
|
||||
***
|
||||
|
||||
## Tech Stacks
|
||||
|
||||
- JDK 17
|
||||
- Kotlin 1.6.21
|
||||
- Build Tools
|
||||
- Gradle
|
||||
- Kotlin DSL
|
||||
- Spring Boot 2
|
||||
- Spring Data JPA
|
||||
- MariaDB 10.8.3
|
||||
- OpenAPI Specification
|
||||
- Swagger v3
|
||||
- springdoc-openapi ui 1.6.13
|
||||
|
||||
***
|
||||
|
||||
## 프로젝트 구성
|
||||
|
||||
프로젝트는 멀티 모듈로 구성되어있습니다.
|
||||
|
||||
<img width="344" alt="architecture-1" src="https://user-images.githubusercontent.com/31076826/204638756-a9a8b9b8-d0e5-4a27-bf14-4c8f12e93448.png">
|
||||
|
||||
- core
|
||||
- 헥사고날 아키텍처의 application core 영역에 해당
|
||||
- 프로젝트의 핵심적인 비즈니스 로직이 들어있습니다
|
||||
- domain, port를 포함하고 있으며, 모든 클래스는 public 접근제한자로 설정되어 있습니다.
|
||||
- infrastructure
|
||||
- 헥사고날 아키텍처의 `adapter - out` 영역에 해당
|
||||
- datasource에 관련된 모듈이 들어갑니다.
|
||||
- persistence adapter, JpaRepository, ORM Entity 가 포함되어있습니다.
|
||||
- server
|
||||
- 헥사고날 아키텍처의 `adapter - in` 영역에 해당
|
||||
- controller를 포함하고 있으며, 모든 클래스는 internal 접근제한자로 설정되어 있습니다.
|
||||
- util
|
||||
- core, server, infrastructure 모듈에서 공통적으로 사용할 유틸이 들어있습니다.
|
||||
|
||||
***
|
||||
|
||||
## demo-app
|
||||
|
||||
demo 웹 애플리케이션의 실행 진입점은 `server - demo-app` 모듈의 DemoAppApplication 입니다.
|
||||
|
||||
<img width="779" alt="DemoAppApplication" src="https://user-images.githubusercontent.com/31076826/204640445-cfcfb9db-a35b-492c-b6d2-4cf7c05030fb.png">
|
||||
<br><br>
|
||||
|
||||
demo-app은 아래와 같이 `:util:common-util`, `:core:demo-core`, `:infrastructure:datastore-mariadb` 모듈을 포함합니다.
|
||||
|
||||
<img width="724" alt="build.gradle.kts" src="https://user-images.githubusercontent.com/31076826/204640772-f1846649-a21d-459a-9883-3dae61b44536.png">
|
||||
@@ -3,6 +3,7 @@ plugins {
|
||||
id("io.spring.dependency-management") version "1.0.13.RELEASE"
|
||||
kotlin("jvm") version "1.6.21"
|
||||
kotlin("plugin.spring") version "1.6.21"
|
||||
kotlin("plugin.jpa") version "1.6.21"
|
||||
kotlin("kapt") version "1.6.21"
|
||||
}
|
||||
|
||||
@@ -18,7 +19,7 @@ configurations {
|
||||
|
||||
allprojects {
|
||||
group = "me.jiniworld"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
6
core/demo-core/build.gradle.kts
Normal file
6
core/demo-core/build.gradle.kts
Normal file
@@ -0,0 +1,6 @@
|
||||
dependencies {
|
||||
implementation("org.springframework.data:spring-data-commons")
|
||||
implementation("org.springframework:spring-tx")
|
||||
|
||||
implementation(project(":util:common-util"))
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package me.jiniworld.demohx.domain
|
||||
package me.jiniworld.demohx.application.notice.domain
|
||||
|
||||
import me.jiniworld.demohx.application.port.output.NoticeDetail
|
||||
import me.jiniworld.demohx.application.port.output.NoticeSimple
|
||||
import me.jiniworld.demohx.util.DateTimeUtils
|
||||
import me.jiniworld.demohx.DateTimeUtils
|
||||
import me.jiniworld.demohx.application.notice.port.output.NoticeDetail
|
||||
import me.jiniworld.demohx.application.notice.port.output.NoticeSimple
|
||||
import java.time.LocalDateTime
|
||||
|
||||
data class Notice(
|
||||
@@ -0,0 +1,10 @@
|
||||
package me.jiniworld.demohx.application.notice.port.input
|
||||
|
||||
import me.jiniworld.demohx.application.notice.port.output.NoticeDetail
|
||||
import me.jiniworld.demohx.application.notice.port.output.NoticeSimple
|
||||
import org.springframework.data.domain.Pageable
|
||||
|
||||
interface GetNoticeQuery {
|
||||
fun getNoticeSimple(command: GetNoticesCommand): List<NoticeSimple>?
|
||||
fun getNoticeDetail(noticeId: Long): NoticeDetail?
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package me.jiniworld.demohx.application.notice.port.input
|
||||
|
||||
data class GetNoticesCommand(
|
||||
val page: Int,
|
||||
val size: Int,
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
package me.jiniworld.demohx.application.notice.port.output
|
||||
|
||||
import me.jiniworld.demohx.application.notice.domain.Notice
|
||||
import org.springframework.data.domain.Pageable
|
||||
|
||||
interface LoadNoticePort {
|
||||
fun loadNotices(pageable: Pageable): List<Notice>?
|
||||
fun loadNotice(id: Long): Notice?
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.jiniworld.demohx.application.port.output
|
||||
package me.jiniworld.demohx.application.notice.port.output
|
||||
|
||||
data class NoticeDetail(
|
||||
val id: Long,
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.jiniworld.demohx.application.port.output
|
||||
package me.jiniworld.demohx.application.notice.port.output
|
||||
|
||||
data class NoticeSimple(
|
||||
val id: Long,
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.jiniworld.demohx.application.notice.service
|
||||
|
||||
import me.jiniworld.demohx.annotation.UseCase
|
||||
import me.jiniworld.demohx.application.notice.port.input.GetNoticeQuery
|
||||
import me.jiniworld.demohx.application.notice.port.input.GetNoticesCommand
|
||||
import me.jiniworld.demohx.application.notice.port.output.LoadNoticePort
|
||||
import me.jiniworld.demohx.application.notice.port.output.NoticeDetail
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@UseCase
|
||||
internal class GetNoticeService(
|
||||
private val loadNoticePort: LoadNoticePort,
|
||||
) : GetNoticeQuery {
|
||||
|
||||
override fun getNoticeSimple(command: GetNoticesCommand) =
|
||||
loadNoticePort.loadNotices(PageRequest.of(command.page, command.size, Sort.by(Sort.Order.desc("id"))))
|
||||
?.map { it.mapToNoticeSimple() }
|
||||
|
||||
override fun getNoticeDetail(id: Long): NoticeDetail? =
|
||||
loadNoticePort.loadNotice(id)?.mapToNoticeDetail()
|
||||
}
|
||||
9
infrastructure/datastore-mariadb/build.gradle.kts
Normal file
9
infrastructure/datastore-mariadb/build.gradle.kts
Normal file
@@ -0,0 +1,9 @@
|
||||
apply(plugin = "kotlin-jpa")
|
||||
|
||||
dependencies {
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
|
||||
|
||||
implementation(project(":util:common-util"))
|
||||
implementation(project(":core:demo-core"))
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.jiniworld.demohx.adapter.output.persistence
|
||||
package me.jiniworld.demohx.persistence.notice
|
||||
|
||||
import me.jiniworld.demohx.domain.Notice
|
||||
import me.jiniworld.demohx.application.notice.domain.Notice
|
||||
import org.springframework.data.annotation.CreatedDate
|
||||
import org.springframework.data.annotation.LastModifiedDate
|
||||
import java.time.LocalDateTime
|
||||
@@ -0,0 +1,20 @@
|
||||
package me.jiniworld.demohx.persistence.notice
|
||||
|
||||
import me.jiniworld.demohx.annotation.PersistenceAdapter
|
||||
import me.jiniworld.demohx.application.notice.domain.Notice
|
||||
import me.jiniworld.demohx.application.notice.port.output.LoadNoticePort
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
|
||||
@PersistenceAdapter
|
||||
internal class NoticePersistenceAdapter(
|
||||
private val noticeRepository: NoticeRepository,
|
||||
) : LoadNoticePort {
|
||||
override fun loadNotices(pageable: Pageable): List<Notice>? {
|
||||
return noticeRepository.findAllBy(pageable).map { it.mapToNotice() }.toList()
|
||||
}
|
||||
|
||||
override fun loadNotice(id: Long): Notice? {
|
||||
return noticeRepository.findByIdOrNull(id)?.mapToNotice()
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package me.jiniworld.demohx.adapter.output.persistence
|
||||
package me.jiniworld.demohx.persistence.notice
|
||||
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
internal interface NoticeRepository: JpaRepository<NoticeEntity, Long> {
|
||||
fun findAllBy(pageable: Pageable): List<NoticeEntity>
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
dependencies {
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||
compileOnly("org.springframework.boot:spring-boot-configuration-processor")
|
||||
implementation("org.springdoc:springdoc-openapi-ui:1.6.13")
|
||||
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
|
||||
|
||||
implementation(project(":util:common-util"))
|
||||
implementation(project(":core:demo-core"))
|
||||
implementation(project(":infrastructure:datastore-mariadb"))
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.jiniworld.demohx
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
import java.util.*
|
||||
|
||||
@SpringBootApplication(scanBasePackages = [
|
||||
"me.jiniworld.demohx.config",
|
||||
"me.jiniworld.demohx.web",
|
||||
"me.jiniworld.demohx.application",
|
||||
"me.jiniworld.demohx.persistence",
|
||||
])
|
||||
class DemoAppApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
Locale.setDefault(Locale.KOREA)
|
||||
runApplication<DemoAppApplication>(*args)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package me.jiniworld.demohx.web.notice
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import me.jiniworld.demohx.annotation.WebAdapter
|
||||
import me.jiniworld.demohx.application.notice.port.input.GetNoticeQuery
|
||||
import me.jiniworld.demohx.application.notice.port.input.GetNoticesCommand
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
||||
@WebAdapter
|
||||
@Tag(name = "setting-system", description = "설정-시스템(공지사항, FAQ, 이용약관, 메타정보 등)")
|
||||
@RestController
|
||||
@RequestMapping("/v1/notices")
|
||||
internal class GetNoticeController(
|
||||
private val getNoticeQuery: GetNoticeQuery,
|
||||
) {
|
||||
|
||||
@Operation(summary = "공지사항 목록")
|
||||
@GetMapping("")
|
||||
fun notices(
|
||||
@RequestParam(value = "page", required = false, defaultValue = "0") page: Int,
|
||||
@RequestParam(value = "size", required = false, defaultValue = "10") size: Int,
|
||||
) = getNoticeQuery.getNoticeSimple(GetNoticesCommand(page = page, size = size))
|
||||
|
||||
@Operation(summary = "공지사항 상세조회")
|
||||
@GetMapping("/{notice_id}")
|
||||
fun notice(@PathVariable("notice_id") noticeId: Long) =
|
||||
getNoticeQuery.getNoticeDetail(noticeId)
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
spring:
|
||||
application:
|
||||
name: chaeking
|
||||
name: demo-app
|
||||
profiles:
|
||||
active: local
|
||||
config:
|
||||
@@ -31,8 +31,8 @@ spring:
|
||||
open-in-view: false
|
||||
show-sql: true
|
||||
|
||||
devtools:
|
||||
add-properties: false
|
||||
# devtools:
|
||||
# add-properties: false
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
7
server/demo-app/src/main/resources/banner.txt
Normal file
7
server/demo-app/src/main/resources/banner.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
___ ____ _ _ ____ ____ ___ ___
|
||||
| \ |___ |\/| | | __ |__| |__] |__]
|
||||
|__/ |___ | | |__| | | | |
|
||||
|
||||
${Ansi.GREEN}:: Spring Boot :: ${Ansi.NORMAL}${spring-boot.formatted-version}${Ansi.NORMAL}
|
||||
${application.title}${application.formatted-version}
|
||||
@@ -1,3 +1,11 @@
|
||||
|
||||
rootProject.name = "demo-hexagonal"
|
||||
include("web")
|
||||
include("core:demo-core")
|
||||
findProject(":core:demo-core")?.name = "demo-core"
|
||||
include("infrastructure:datastore-mariadb")
|
||||
findProject(":infrastructure:datastore-mariadb")?.name = "datastore-mariadb"
|
||||
include("server")
|
||||
include("server:demo-app")
|
||||
findProject(":server:demo-app")?.name = "demo-app"
|
||||
include("util:common-util")
|
||||
findProject(":util:common-util")?.name = "common-util"
|
||||
|
||||
2
util/common-util/build.gradle.kts
Normal file
2
util/common-util/build.gradle.kts
Normal file
@@ -0,0 +1,2 @@
|
||||
dependencies {
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
package me.jiniworld.demohx.util
|
||||
package me.jiniworld.demohx
|
||||
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.temporal.ChronoField
|
||||
import java.time.temporal.TemporalAdjusters
|
||||
|
||||
object DateTimeUtils {
|
||||
|
||||
private const val SIMPLE_PATTERN_MONTH = "yyyyMM"
|
||||
private const val SIMPLE_PATTERN_DATE = "yyyyMMdd"
|
||||
private const val DEFAULT_PATTERN_DATE = "yyyy-MM-dd"
|
||||
@@ -36,27 +34,9 @@ object DateTimeUtils {
|
||||
fun getLastDateTime(date: LocalDate): LocalDateTime =
|
||||
LocalDateTime.of(date.with(TemporalAdjusters.lastDayOfMonth()), LOCALTIME_END)
|
||||
|
||||
fun getFirstDateTime(date: LocalDate, type: AnalysisType): LocalDateTime =
|
||||
when (type) {
|
||||
AnalysisType.weekly -> LocalDateTime.of(date.minusDays((date[ChronoField.DAY_OF_WEEK] - 1).toLong()).minusWeeks(6), LOCALTIME_START)
|
||||
AnalysisType.monthly -> date.minusDays((date[ChronoField.DAY_OF_MONTH] - 1).toLong()).minusMonths(6).atStartOfDay()
|
||||
else -> LocalDateTime.of(date.minusDays((date[ChronoField.DAY_OF_WEEK] - 1).toLong()), LOCALTIME_START)
|
||||
}
|
||||
fun toString(date: LocalDate): String = date.format(FORMATTER_DATE)
|
||||
|
||||
fun getLastDateTime(date: LocalDate, type: AnalysisType): LocalDateTime =
|
||||
when (type) {
|
||||
AnalysisType.monthly -> LocalDateTime.of(date.minusDays(date[ChronoField.DAY_OF_MONTH].toLong()).plusMonths(1), LOCALTIME_END)
|
||||
else -> LocalDateTime.of(date.plusDays((7 - date[ChronoField.DAY_OF_WEEK]).toLong()), LOCALTIME_END)
|
||||
}
|
||||
fun toString(dateTime: LocalDateTime): String = dateTime.format(FORMATTER_DATETIME)
|
||||
|
||||
fun toString(date: LocalDate) = date.format(FORMATTER_DATE)
|
||||
|
||||
fun toString(dateTime: LocalDateTime) = dateTime.format(FORMATTER_DATETIME)
|
||||
|
||||
fun toDateString(dateTime: LocalDateTime) = dateTime.format(FORMATTER_DATE)
|
||||
}
|
||||
|
||||
|
||||
enum class AnalysisType {
|
||||
daily, weekly, monthly
|
||||
fun toDateString(dateTime: LocalDateTime) : String = dateTime.format(FORMATTER_DATE)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package me.jiniworld.demohx.annotation
|
||||
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MustBeDocumented
|
||||
@Component
|
||||
annotation class PersistenceAdapter(
|
||||
val value: String = ""
|
||||
)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package me.jiniworld.demohx.annotation
|
||||
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MustBeDocumented
|
||||
@Component
|
||||
annotation class UseCase(
|
||||
val value: String = ""
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package me.jiniworld.demohx.annotation
|
||||
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MustBeDocumented
|
||||
@Component
|
||||
annotation class WebAdapter(
|
||||
val value: String = ""
|
||||
)
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package me.jiniworld.demohx
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
import java.util.*
|
||||
|
||||
@SpringBootApplication
|
||||
class DemoHxApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
Locale.setDefault(Locale.KOREA)
|
||||
runApplication<DemoHxApplication>(*args)
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package me.jiniworld.demohx.adapter.input.web
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import me.jiniworld.demohx.application.service.GetNoticeService
|
||||
import me.jiniworld.demohx.domain.Notice
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@Component
|
||||
//@WebAdapter
|
||||
@Tag(name = "setting-system", description = "설정-시스템(공지사항, FAQ, 이용약관, 메타정보 등)")
|
||||
@RestController
|
||||
@RequestMapping("/v1/notices")
|
||||
internal class GetNoticeController(
|
||||
private val getNoticeQuery: GetNoticeService,
|
||||
) {
|
||||
|
||||
@Operation(summary = "공지사항 목록")
|
||||
@GetMapping("")
|
||||
fun notices(
|
||||
@RequestParam(value = "page", required = false, defaultValue = "0") page: Int,
|
||||
@RequestParam(value = "size", required = false, defaultValue = "10") size: Int,
|
||||
): List<Notice> {
|
||||
println(">>>>>>>>> 1")
|
||||
return getNoticeQuery.getNoticeSimple(PageRequest.of(page, size, Sort.by(Sort.Order.desc("id"))))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package me.jiniworld.demohx.adapter.output.persistence
|
||||
|
||||
import me.jiniworld.demohx.application.port.output.LoadNoticePort
|
||||
import me.jiniworld.demohx.domain.Notice
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.stereotype.Component
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Component
|
||||
internal class NoticePersistenceAdapter(
|
||||
private val noticeRepository: NoticeRepository,
|
||||
) : LoadNoticePort {
|
||||
override fun loadNotices(pageable: Pageable): List<Notice> {
|
||||
|
||||
println(">>>>>>>>> 3")
|
||||
return noticeRepository.findAllBy(pageable).map { it.mapToNotice() }.toList()
|
||||
}
|
||||
|
||||
override fun loadNotice(id: Long): Notice? {
|
||||
return Notice(id = id, title = "zzz", content = "fff", createdAt = LocalDateTime.now())
|
||||
// return noticeRepository.findById(id)?.map(NoticeEntity::mapToNotice)
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package me.jiniworld.demohx.application.port.input
|
||||
|
||||
import me.jiniworld.demohx.domain.Notice
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
interface GetNoticeQuery {
|
||||
fun getNoticeSimple(pageable: Pageable): List<Notice>
|
||||
fun getNoticeDetail(noticeId: Long): Notice?
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package me.jiniworld.demohx.application.port.output
|
||||
|
||||
import me.jiniworld.demohx.domain.Notice
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
interface LoadNoticePort {
|
||||
fun loadNotices(pageable: Pageable): List<Notice>
|
||||
fun loadNotice(id: Long): Notice?
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package me.jiniworld.demohx.application.service
|
||||
|
||||
import me.jiniworld.demohx.application.port.input.GetNoticeQuery
|
||||
import me.jiniworld.demohx.application.port.output.LoadNoticePort
|
||||
import me.jiniworld.demohx.domain.Notice
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.sql.DriverManager.println
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Component
|
||||
internal class GetNoticeService(
|
||||
private val loadNoticePort: LoadNoticePort,
|
||||
) : GetNoticeQuery {
|
||||
|
||||
override fun getNoticeSimple(pageable: Pageable): List<Notice> {
|
||||
println(">>>>>>>>> 2")
|
||||
return loadNoticePort.loadNotices(pageable)
|
||||
// return loadNoticePort.loadNotices(pageable).map { it.mapToNoticeSimple() }.toList()
|
||||
}
|
||||
|
||||
override fun getNoticeDetail(id: Long): Notice? {
|
||||
return loadNoticePort.loadNotice(id)
|
||||
// return loadNoticePort.loadNotice(id)?.mapToNoticeDetail()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user