Java Collection을 DB로

토토들·2026년 8월 14일

면접을 조져서 내가 애매하게 알았던 내용을 보다 확실히 잡아둬야겠다.

우선 Java Collection으로 DB를 삼는 내용을 잘 몰랐다.
Spring에서 늘상 JPA만 쓰다보니 기본 개념을 까먹고 있었던 것 같다.

항공 예약시스템을 구현하면서 따라가보겠다.

요구사항은 이렇다.
1. 항공편을 등록할 수 있어야 한다.
2. 전체 항공편 목록을 조회할 수 있어야 한다.
3. 특정 항공편의 정보를 조회할 수 있어야 한다.
4. 사용자는 특정 항공편의 특정 좌석을 예약할 수 있어야 한다.
5. 이미 예약된 좌석은 다시 예약할 수 없다.
6. 예약을 취소할 수 있어야 한다.
7. 사용자의 전체 예약 내역을 조회할 수 있어야 한다.
8. 존재하지 않는 항공편, 좌석, 사용자, 예약을 요청한 경우 적절한 예외를 발생시켜야 한다.
9. 데이터베이스는 사용하지 않는다.
10. 프로그램이 실행되는 동안 데이터는 메모리에 저장한다.

우선 항공편 도메인 객체인 Flight부터 만들어주겠다.
Entity는 똑같이 만들어준다.

Flight

package com.test.javatest.flight.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Flight {
    private int flightNumber;
    private String departure;
    private String destination;
}

이후, Jpa가 Repository를 통해 DB에 접근했던 것 같이, 똑같이 Repository로 접근을 하면 되는데 이걸 헷갈려서 그냥 접근해버린 게 문제가 됐다.
즉, Repository에서 DB를 초기화해주고 접근하는 코드까지 만들어주면 된다는 것.

FlightRepository

package com.test.javatest.flight.repository;

import com.test.javatest.flight.domain.Flight;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
public class FlightRepository {
	// 메모리 저장소
    private final Map<Long, Flight> flightDB = new HashMap<>();
    // PK
    private static Long id = 0L;
    // flight 를 저장하면 id를 리턴한다.
    public Long register(Flight flight) {
        flightDB.put(id, flight);
        Long temp = id;
        id++;
        return temp;
    }

    public Set<Long> readId() {
        return flightDB.keySet();
    }

    public Flight readValue(Long id) {
        return flightDB.get(id);
    }

    public List<Flight> readByFlightId(int flightId) {
        Collection<Flight> flightList = flightDB.values();

        List<Flight> list = new ArrayList<>();
        for (Flight flight: flightList) {
            if (flight.getFlightNumber() == flightId) {
                list.add(flight);
            }
        }

        return list;
    }

    public Long findByFlight(Flight flight) {
        for (Map.Entry<Long, Flight> entry : flightDB.entrySet()) {
            if (entry.getValue().equals(flight)) {
                return entry.getKey();
            }
        }

        return 0L;
    }
}

이후 Service에서 서비스 로직 처리를 해주고 Controller에 연동을 시키면 끝.

FlightService

package com.test.javatest.flight.service;

import com.test.javatest.flight.domain.Flight;
import com.test.javatest.flight.dto.FlightDto;
import com.test.javatest.flight.repository.FlightRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
@RequiredArgsConstructor
public class FlightService {
    private final FlightRepository flightRepository;

    public Long register(FlightDto.RegisterRequest request) {
        Flight flight = Flight
                .builder()
                .flightNumber(request.getFlightNumber())
                .departure(request.getDeparture())
                .destination(request.getDestination())
                .build();

        return flightRepository.register(flight);
    }

    public List<FlightDto.GetResponse> read() {
        Set<Long> ids = flightRepository.readId();

        List<FlightDto.GetResponse> list = new ArrayList<>();

        for (Long id: ids) {
            Flight flight = flightRepository.readValue(id);
            FlightDto.GetResponse response = FlightDto.GetResponse
                    .builder()
                    .id(id)
                    .flightNumber(flight.getFlightNumber())
                    .departure(flight.getDeparture())
                    .destination(flight.getDestination())
                    .build();

            list.add(response);
        }

        return list;
    }

    public List<FlightDto.GetResponse> readByFlightId(int flightId) {
        List<Flight> flights = flightRepository.readByFlightId(flightId);

        List<FlightDto.GetResponse> responseList = new ArrayList();


        for (Flight flight: flights) {
            Long id = flightRepository.findByFlight(flight);

            responseList.add(FlightDto.GetResponse
                    .builder()
                    .id(id)
                    .flightNumber(flight.getFlightNumber())
                    .departure(flight.getDeparture())
                    .destination(flight.getDestination())
                    .build());
        }
        return responseList;
    }


}

FlightController

package com.test.javatest.flight.controller;

import com.test.javatest.flight.dto.FlightDto;
import com.test.javatest.flight.service.FlightService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/flight")
public class FlightController {

    private final FlightService flightService;

    @PostMapping
    public ResponseEntity<Long> register(@RequestBody FlightDto.RegisterRequest request) {
        return ResponseEntity.ok(flightService.register(request));
    }

    @GetMapping
    public ResponseEntity<List<FlightDto.GetResponse>> read() {
        return ResponseEntity.ok(flightService.read());
    }

    @GetMapping("/{flightId}")
    public ResponseEntity<List<FlightDto.GetResponse>> readByFlightId(@PathVariable int flightId) {
        return ResponseEntity.ok(flightService.readByFlightId(flightId));
    }
}

다음편에서 현 코드 리펙토링을 진행하겠습니다.

profile
패션과 개발을 좋아합니다.

0개의 댓글