Published 2023. 1. 1. 15:09
반응형
1:1 관계 예제
- 1:1 관계는 1:N 관계와 거의 유사
- 상황 : 영화관에 자리가 여러개 존재하고 고객이 자리를 선택해야 하는 상황
- 고객은 자리를 하나만 선택할 수 있고, 자리도 한 고객에게만 선택될 수 있는 1:1 관계
- Customer 객체에는 id와 name 정보가 들어가고, Seat 객체에는 id, rowId(A
C), colId(15) 정보가 들어감 - 각각의 id가 primary key(기본키)로 지정
- 연관관계 매핑
- 1:N 관계에서는 보통 N쪽을 연관관계의 주인으로 지정
- 1:1 관계에서도 연관관계의 주인을 지정해야 함
- 어느쪽을 주인으로 지정해도 상관 없지만 보통은 foreign key가 있는쪽을 주인으로 지정
- 이 예제에서는 아래와 같이 Customer에 foreign key를 가져오고 주인으로 정했음
구현 코드
Customer Entity
- 위에서 언급했든 Customer을 연관관계 주인으로 지정
- 연관관계 주인 => @JoinColumn으로 column명 지정
- @OneToOne => default가 FetchType.EAGER이기 때문에 FetchType.LAZY로 지정
@Entity
@Data
public class Customer {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_id")
private Long id;
private String name;
// 연관관계 매핑
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "seat_id")
private Seat seat;
}
Seat Entity
- 연관관계의 주인이 아님 => mappedBy 사용
- Seat도 마찬가지로 @OneToOne이기 때문에 FetchType.LAZY로 지정
@Entity
@Data
public class Seat {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "seat_id")
private Long id;
private String rowId;
private Integer colId;
// 연관관계 매핑
@OneToOne(mappedBy = "seat", fetch = FetchType.LAZY)
private Customer customer;
}
@PostConstruct를 사용한 초기 데이터 생성
- Customer 1, 2, 3과 Seat 15개 (A1~C5) 를 추가하고자 함
- 일일이 DB에 삽입할 수 있지만 @PostConstruct 어노테이션을 사용하여 서버가 실행될 때 데이터를 한 번에 삽입해 줄 수 있음
- 반복문을 사용하기 때문에 매우 간편
- 매번 실행할 때마다 추가되기 때문에 DB의 ddl-auto가 create나 create-drop이 아닌 경우 데이터가 중복으로 추가될 수 있으니 주의
@Component
@RequiredArgsConstructor
public class MakeInitData {
private final CustomerRepository customerRepository;
private final SeatRepository seatRepository;
@PostConstruct
public void makeSeatAndCustomer() {
for(char rowId = 'A' ; rowId <= 'C' ; rowId ++) {
for(int colId = 1 ; colId <= 5 ; colId ++) {
Seat seat = new Seat();
seat.setRowId(String.valueOf(rowId));
seat.setColId(colId);
seatRepository.save(seat);
}
}
for(int i = 1 ; i <= 3 ; i ++) {
Customer customer = new Customer();
customer.setName("customer" + i);
customerRepository.save(customer);
}
}
}
초기 데이터 생성 결과
좌석 예약
- customerId와 seatId를 입력받아 좌석 예약
- 입력받을 때는 DTO 사용 (DTO 코드 생략)
@PostMapping("/reservation")
public String reservation(@RequestBody ReservationRequest request) {
Customer customer = customerRepository.findById(request.getCustomerId()).get();
Seat seat = seatRepository.findById(request.getSeatId()).get();
customer.setSeat(seat);
customerRepository.save(customer);
return String.format("%s 손님 (%s, %d) 좌석 예약 성공", customer.getName(), seat.getRowId(), seat.getColId());
}
좌석 예약 결과
좌석 예약 확인
- rowId와 colId를 입력받아 해당 좌석이 예약되어 있는지 확인
- 입력받을 때는 DTO 사용 (DTO 코드 생략)
@GetMapping("/reservation-check")
public String reservationCheck(@RequestBody ReservationCheckRequest request) {
Seat seat = seatRepository.findByRowIdAndColId(request.getRowId(), request.getColId()).get();
if(seat.getCustomer() == null) {
return String.format("(%s, %d) 좌석은 예약되지 않았습니다.", request.getRowId(), request.getColId());
} else {
return String.format("(%s, %d) 좌석 예약 손님 : %s", request.getRowId(), request.getColId(), seat.getCustomer().getName());
}
}
좌석 예약 확인
반응형
'Spring Boot > 문법 정리' 카테고리의 다른 글
[Spring Boot] 로그인 구현 방법 정리 (6) | 2023.01.01 |
---|---|
[Spring Boot] 연관관계 매핑 - N:M 관계 예제 (0) | 2023.01.01 |
[Spring Boot] 연관관계 매핑 - 1:N 관계 예제 (+FetchType.LAZY) (0) | 2022.12.31 |
[Spring Boot] 연관관계 매핑 - 1:1, 1:N, N:M (0) | 2022.12.31 |
[Spring Boot] Swagger 3.0 적용 (0) | 2022.07.09 |