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 코드로도 변환해줄 수 있다.