Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] - Flyway 마이그레이션 단계 세분화(그런데 이제 안전한 마이그레이션 플랜을 곁들인...) #476

Merged
merged 8 commits into from
Sep 26, 2024
93 changes: 93 additions & 0 deletions backend/src/main/java/kr/touroot/place/domain/Place.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package kr.touroot.place.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import kr.touroot.global.entity.BaseEntity;
import kr.touroot.global.exception.BadRequestException;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(indexes = @Index(name = "place_name_latitude_longitude_idx", columnList = "name, latitude, longitude"))
public class Place extends BaseEntity {

private static final Pattern LATITUDE_PATTERN = Pattern.compile("^([-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?))$");
private static final Pattern LONGITUDE_PATTERN = Pattern.compile(
"^([-+]?((1[0-7]\\d(\\.\\d+)?|180(\\.0+)?)|([1-9]?\\d(\\.\\d+)?)))$");
private static final int PLACE_NAME_MAX_LENGTH = 60;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String latitude;

@Column(nullable = false)
private String longitude;

private String googlePlaceId;

public Place(Long id, String name, String latitude, String longitude, String googlePlaceId) {
validate(name, latitude, longitude, googlePlaceId);
this.id = id;
this.name = name;
this.latitude = latitude;
this.longitude = longitude;
this.googlePlaceId = googlePlaceId;
}

public Place(String name, String latitude, String longitude, String googlePlaceId) {
this(null, name, latitude, longitude, googlePlaceId);
}

public Place(String name, String latitude, String longitude) {
this(null, name, latitude, longitude, null);
}

private void validate(String name, String latitude, String longitude, String googlePlaceId) {
validateNotNull(name, latitude, longitude);
validateBlank(name, latitude, longitude);
validateLatitudeLongitudeFormat(latitude, longitude);
validatePlaceNameLength(name);
}

private void validateNotNull(String name, String latitude, String longitude) {
if (name == null || latitude == null || longitude == null) {
throw new BadRequestException("장소 이름, 위도, 경도는 비어 있을 수 없습니다");
}
}

private void validateBlank(String name, String latitude, String longitude) {
if (name.isBlank() || latitude.isBlank() || longitude.isBlank()) {
throw new BadRequestException("장소 이름, 위도, 경도는 비어 있을 수 없습니다");
}
}

private void validateLatitudeLongitudeFormat(String latitude, String longitude) {
Matcher latitudeMatcher = LATITUDE_PATTERN.matcher(latitude);
Matcher longitudeMatcher = LONGITUDE_PATTERN.matcher(longitude);
if (!latitudeMatcher.find() || !longitudeMatcher.find()) {
throw new BadRequestException("위,경도의 형식이 올바르지 않습니다");
}
}

private void validatePlaceNameLength(String placeName) {
if (placeName.length() > PLACE_NAME_MAX_LENGTH) {
throw new BadRequestException("장소 이름은 " + PLACE_NAME_MAX_LENGTH + "자 이하여야 합니다");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.List;
import kr.touroot.global.entity.BaseEntity;
import kr.touroot.global.exception.BadRequestException;
import kr.touroot.place.domain.Place;
import kr.touroot.position.domain.Position;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
Expand Down Expand Up @@ -50,6 +51,9 @@ public class TraveloguePlace extends BaseEntity {
@Embedded
private Position position;

@ManyToOne(fetch = FetchType.LAZY)
private Place place;

@JoinColumn(nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
private TravelogueDay travelogueDay;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.List;
import kr.touroot.global.entity.BaseEntity;
import kr.touroot.global.exception.BadRequestException;
import kr.touroot.place.domain.Place;
import kr.touroot.position.domain.Position;
import lombok.AccessLevel;
import lombok.Getter;
Expand Down Expand Up @@ -49,6 +50,9 @@ public class TravelPlanPlace extends BaseEntity {
@Embedded
private Position position;

@ManyToOne(fetch = FetchType.LAZY)
private Place place;

@OneToMany(mappedBy = "travelPlanPlace", cascade = CascadeType.ALL, orphanRemoval = true)
private List<TravelPlaceTodo> travelPlaceTodos = new ArrayList<>();

Expand Down
50 changes: 0 additions & 50 deletions backend/src/main/resources/db/migration/mysql/V2__delete_place.sql

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-- travelogue_place 외래 키 제약 조건 삭제
ALTER TABLE travelogue_place
DROP FOREIGN KEY fk_travelogue_place_place_id;

-- travel_plan_place 외래 키 제약 조건 삭제
ALTER TABLE travel_plan_place
DROP FOREIGN KEY fk_travel_plan_place_place_id;

-- travelogue_place 테이블에 latitude, longitude, name 컬럼 추가
ALTER TABLE travelogue_place
ADD latitude VARCHAR(255),
ADD longitude VARCHAR(255),
ADD name VARCHAR(255);

-- travel_plan_place 테이블에 latitude, longitude, name 컬럼 추가
ALTER TABLE travel_plan_place
ADD latitude VARCHAR(255),
ADD longitude VARCHAR(255),
ADD name VARCHAR(255);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- 오늘 이전의 place 테이블의 데이터로 travelogue_place 업데이트
UPDATE travelogue_place tp
JOIN place p ON tp.place_id = p.id
SET tp.latitude = p.latitude, tp.longitude = p.longitude, tp.name = p.name
WHERE DATE(p.created_at) < DATE(NOW());

-- 오늘 이전의 place 테이블의 데이터로 travel_plan_place 업데이트
UPDATE travel_plan_place tpp
JOIN place p ON tpp.place_id = p.id
SET tpp.latitude = p.latitude, tpp.longitude = p.longitude, tpp.name = p.name
WHERE DATE(p.created_at) < DATE(NOW());
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- 남은 모든 Place 데이터 이동
UPDATE travelogue_place tp
JOIN place p ON tp.place_id = p.id
SET tp.latitude = p.latitude, tp.longitude = p.longitude, tp.name = p.name;

UPDATE travel_plan_place tpp
JOIN place p ON tpp.place_id = p.id
SET tpp.latitude = p.latitude, tpp.longitude = p.longitude, tpp.name = p.name;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- travelogue_place NOT NULL 제약 조건 추가
ALTER TABLE travelogue_place
MODIFY latitude VARCHAR(255) NOT NULL,
MODIFY longitude VARCHAR(255) NOT NULL,
MODIFY name VARCHAR(255) NOT NULL;

-- travel_plan_place NOT NULL 제약 조건 추가
ALTER TABLE travel_plan_place
MODIFY latitude VARCHAR(255) NOT NULL,
MODIFY longitude VARCHAR(255) NOT NULL,
MODIFY name VARCHAR(255) NOT NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- travelogue 테이블 index 추가
CREATE INDEX travelogue_like_count_idx ON travelogue (like_count);
CREATE INDEX travelogue_created_at_idx ON travelogue (created_at);

Loading