CREATE TABLE bakery_review (
review_id INT AUTO_INCREMENT PRIMARY KEY, -- 리뷰 ID (고유 번호)
bakery_name VARCHAR(255) NOT NULL, -- 빵집 이름
review_contents TEXT NOT NULL, -- 리뷰 내용
bakery_phone VARCHAR(15), -- 빵집 전화번호
operating_hours VARCHAR(255), -- 운영 시간
parking_info VARCHAR(255), -- 주차 정보
menu_info TEXT, -- 메뉴 정보
latitude DECIMAL(10, 7) NOT NULL, -- 위도
longitude DECIMAL(10, 7) NOT NULL, -- 경도
area VARCHAR(100) NOT NULL, -- 지역 카테고리
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 생성 날짜
);


음 근데 나는 테이블에 데이터를 직접 삽입하는게 아니라, 관리자만 글을 쓸 수 있도록해서 글쓰기를 등록하면 그 값들이 db에 넘어가도록 하려고 하거든 그럼 위도와 경도는 어떡해?
위도와 경도를 직접 삽입하지 않고, 관리자 페이지에서 글을 작성하면서 자연스럽게 위도와 경도 데이터를 입력받으려면 지도 API를 활용해 입력 폼에서 좌표를 자동으로 가져오는 방식으로 구현하는 것이 좋습니다. 아래는 이를 구현하는 전체 흐름입니다.
HTML 폼에 지도 API를 연동하여, 관리자가 빵집 위치를 선택하거나 주소를 입력하면 자동으로 위도와 경도를 가져오도록 만듭니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>빵집 리뷰 등록</title>
<script type="text/javascript" src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=YOUR_CLIENT_ID"></script>
<style>
#map { width: 100%; height: 400px; margin-bottom: 20px; }
</style>
</head>
<body>
<h1>빵집 리뷰 등록</h1>
<form method="POST" action="/bakery-review">
<label for="bakery_name">빵집 이름:</label>
<input type="text" id="bakery_name" name="bakery_name" required><br><br>
<label for="review_contents">리뷰 내용:</label><br>
<textarea id="review_contents" name="review_contents" required></textarea><br><br>
<label for="bakery_phone">전화번호:</label>
<input type="text" id="bakery_phone" name="bakery_phone"><br><br>
<label for="operating_hours">운영 시간:</label>
<input type="text" id="operating_hours" name="operating_hours"><br><br>
<label for="parking_info">주차 정보:</label>
<input type="text" id="parking_info" name="parking_info"><br><br>
<label for="menu_info">메뉴 정보:</label>
<textarea id="menu_info" name="menu_info"></textarea><br><br>
<label for="region">지역:</label>
<input type="text" id="region" name="region" required><br><br>
<!-- 지도 표시 -->
<div id="map"></div>
<label for="latitude">위도:</label>
<input type="text" id="latitude" name="latitude" readonly required><br><br>
<label for="longitude">경도:</label>
<input type="text" id="longitude" name="longitude" readonly required><br><br>
<button type="submit">등록</button>
</form>
<script>
// 지도 초기화
var map = new naver.maps.Map('map', {
center: new naver.maps.LatLng(37.5665, 126.9780), // 초기 위치: 서울
zoom: 10
});
var marker = new naver.maps.Marker({
position: map.getCenter(),
map: map,
draggable: true // 마커를 드래그 가능하게 설정
});
// 마커를 드래그할 때 위도와 경도를 업데이트
naver.maps.Event.addListener(marker, 'dragend', function(e) {
var position = marker.getPosition();
document.getElementById('latitude').value = position.lat();
document.getElementById('longitude').value = position.lng();
});
// 지도를 클릭할 때 마커 이동 및 위도, 경도 업데이트
naver.maps.Event.addListener(map, 'click', function(e) {
var position = e.coord;
marker.setPosition(position);
document.getElementById('latitude').value = position.lat();
document.getElementById('longitude').value = position.lng();
});
</script>
</body>
</html>
VO (Value Object)는 데이터를 담기 위한 객체로, DB의 데이터를 전달하고 받을 때 사용됩니다. BakeryReviewVO는 글쓰기 폼에서 입력되는 데이터를 담는 역할을 합니다.
public class BakeryReviewVO {
private String bakeryName;
private String reviewContents;
private String bakeryPhone;
private String operatingHours;
private String parkingInfo;
private String menuInfo;
private double latitude;
private double longitude;
private String region;
// Getters and Setters
}

@Mapper
public interface BakeryReviewMapper {
void insertReview(BakeryReviewVO bakeryReviewVO); // 리뷰 등록 메서드
}

<mapper namespace="com.example.mapper.BakeryReviewMapper">
<insert id="insertReview">
INSERT INTO bakery_review (bakery_name, review_contents, bakery_phone,
operating_hours, parking_info, menu_info,
latitude, longitude, region, created_at)
VALUES (#{bakeryName}, #{reviewContents}, #{bakeryPhone},
#{operatingHours}, #{parkingInfo}, #{menuInfo},
#{latitude}, #{longitude}, #{region}, NOW())
</insert>
</mapper>

public interface BakeryReviewService {
void createReview(BakeryReviewVO bakeryReviewVO);
}

@Service
public class BakeryReviewServiceImpl implements BakeryReviewService {
private final BakeryReviewMapper bakeryReviewMapper;
// 생성자 주입
public BakeryReviewServiceImpl(BakeryReviewMapper bakeryReviewMapper) {
this.bakeryReviewMapper = bakeryReviewMapper;
}
@Override
public void createReview(BakeryReviewVO bakeryReviewVO) {
// 리뷰 등록
bakeryReviewMapper.insertReview(bakeryReviewVO);
}
}

@Controller
@RequestMapping("/bakery-review")
public class BakeryReviewController {
private final BakeryReviewService bakeryReviewService;
// 생성자 주입
public BakeryReviewController(BakeryReviewService bakeryReviewService) {
this.bakeryReviewService = bakeryReviewService;
}
@PostMapping("/create")
public String createReview(@ModelAttribute BakeryReviewVO bakeryReviewVO) {
// 관리자만 글을 작성할 수 있는 로직 추가 (권한 확인 등)
bakeryReviewService.createReview(bakeryReviewVO); // 서비스 호출하여 리뷰 등록
return "redirect:/bakery-review/list"; // 글 작성 후 리스트 페이지로 리다이렉트
}
}


