[MW] json

Spring Boot(Java 또는 Kotlin)에서 프론트로부터 다음과 같은 JSON:

{ "century": "19C", "duration": ["초","중"] }

를 받아서 각 조합을 실제 날짜 범위 (startDate, endDate)로 변환하는 로직을 아래에 예시로 보여주겠다.


✅ 입력 → 날짜 범위 변환 로직

🔸 전제 기준

  • "19C" → 1801 ~ 1900
  • "초" → 1/3 구간 (1801 ~ 1833)
  • "중" → 2/3 구간 (1834 ~ 1866)
  • "후" → 3/3 구간 (1867 ~ 1900)

✅ Kotlin 기준 Controller + Service 예시

// DTO
data class PeriodRequest(
    val century: String,
    val duration: List<String>
)

data class PeriodRange(
    val startDate: String,  // "yyyyMMdd"
    val endDate: String
)

// Controller
@RestController
@RequestMapping("/api/movies")
class MovieController(
    private val movieService: MovieService
) {
    @PostMapping("/search")
    fun getMovies(@RequestBody request: PeriodRequest): List<PeriodRange> {
        return movieService.convertToRanges(request.century, request.duration)
    }
}

✅ 변환 로직 (Service)

@Service
class MovieService {

    fun convertToRanges(century: String, durations: List<String>): List<PeriodRange> {
        val centuryNum = century.removeSuffix("C").toIntOrNull()
            ?: throw IllegalArgumentException("Invalid century: $century")

        val startYear = (centuryNum - 1) * 100 + 1  // 예: 19C → 1801
        val endYear = centuryNum * 100              // 예: 19C → 1900

        val totalYears = endYear - startYear + 1    // 예: 100년

        return durations.map { duration ->
            val (rangeStart, rangeEnd) = when (duration) {
                "초" -> startYear to (startYear + totalYears / 3 - 1)
                "중" -> (startYear + totalYears / 3) to (startYear + 2 * totalYears / 3 - 1)
                "후" -> (startYear + 2 * totalYears / 3) to endYear
                else -> throw IllegalArgumentException("Invalid duration: $duration")
            }

            PeriodRange(
                startDate = "${rangeStart}0101",
                endDate = "${rangeEnd}1231"
            )
        }
    }
}

✅ 예시 결과

입력:

{ "century": "19C", "duration": ["초","중"] }

결과:

[
  { "startDate": "18010101", "endDate": "18331231" },
  { "startDate": "18340101", "endDate": "18661231" }
]

🔚 참고

  • 날짜 비교를 위한 필터 쿼리 (예: MySQL)에서는 이 값을 기반으로:와 같은 조건으로 처리할 수 있다.
  • WHERE movieBgStart <= '18661231' AND movieBgEnd >= '18010101'

필요하다면 SQL까지 이어서 보여줄 수 있다.


좋다. 앞서 전달한 startDate, endDate 범위를 기준으로, 영화의 시대 배경이 선택된 구간과 겹치는 영화들만 조회하는 SQL 예제를 아래에 정리한다.


✅ 전제

movie 테이블 구조는 다음과 같다고 가정한다:

컬럼명 설명

movie_no 기본키
movie_title 영화 제목
bg_start 배경 시작일 (YYYYMMDD)
bg_end 배경 종료일 (YYYYMMDD)

예시 데이터:

movie_no | movie_title         | bg_start  | bg_end
-----------------------------------------------------
1        | Anne of Green Gables| 18900101  | 19001231
2        | Titanic             | 19000101  | 19121231
3        | Les Misérables      | 18300101  | 18451231

✅ 검색 조건: 19세기 중

startDate = 18340101, endDate = 18661231 일 때, 다음과 같이 배경이 겹치는 영화만 조회할 수 있다.

🔹 단일 구간 조회 SQL

SELECT *
FROM movie
WHERE bg_end >= '18340101'
  AND bg_start <= '18661231';

이 조건은 다음을 의미한다:

  • 영화의 끝나는 시점이 선택된 시작 이후이고
  • 영화의 시작 시점이 선택된 끝 이전이면
  • 선택된 구간과 영화의 시대가 겹친다

✅ 여러 구간일 경우 (예: 초 + 중)

입력 예시:

[
  { "startDate": "18010101", "endDate": "18331231" },
  { "startDate": "18340101", "endDate": "18661231" }
]

🔹 다중 구간 조건 SQL (OR 조건)

SELECT *
FROM movie
WHERE (bg_end >= '18010101' AND bg_start <= '18331231')
   OR (bg_end >= '18340101' AND bg_start <= '18661231');

✅ 참고

  • bg_start, bg_end는 VARCHAR(8) 또는 DATE 타입으로 저장할 수 있음.
  • 성능을 위해 인덱스 (INDEX(bg_start, bg_end)) 추가 권장.
  • Java/Kotlin에서는 동적으로 이 SQL의 OR 조건을 조립해야 함.

필요하다면 JPA Criteria 또는 QueryDSL 코드로도 변환해줄 수 있다.