카테고리 없음

[팀 프로젝트] 24.02.23. 노트

망고고래 2024. 2. 23. 17:59

오늘 할일

1. 리뷰 코드 작성

 

편의시설도 다 API로 받아오는데 굳이 수정 폼을 만들 필요가 있을까...?

그런데 그렇게 생각해보면 owner CRUD도 괜히 만들었다...

아깝긴 한데 이걸 살리려고 괜히 API 데이터 수정하는 폼과 코드를 만드는 건 시간낭비인 것 같다. 추가는 나중에도 할 수 있으니까 일단은 다른 것부터 해야겠다.

 

 

 

1. 리뷰 코드

1)테이블 구성

num(PK) serial
contentSeq(FK) int
star int
text text

여러 테이블에서 contentSeq를 FK로 가져오는 게 가능할까?

그냥 숙소/편의시설/관광지 정보도 전부 다 같은 테이블에 넣어서 관리할까?

그렇게 하면 코드를 상당부분 고쳐야 할 것 같다. FK를 넣지 말까...아니면 리뷰를 카테고리별로 다 나눌까...리뷰 테이블을 나누는 의미는 잘 모르겠지만 그렇게 하면 될 것 같긴 하다. 어차피 지금 리뷰란 모듈화를 못 하고 있어서 컨트롤러는 다 나뉘어있다. 서비스와 리파지토리는 하나를 사용한다고 해도 호출할 때 매개변수로 카테고리명을 넣어주면 테이블 구별해서 넣을 수 있을 듯

구조가 똑같은 테이블을 여러 개 만드는 게 관리하기 번거로워지기만 하는 게 아닌가 하는 생각이 든다. 하지만 개발 경험이 없어서 판단할 수가 없으니 일단은 되는 대로 하고 하는 과정에서 느끼는 점을 다 기록해야겠다.

 

2)리뷰를 불러올 때 해당되는 것이 없다면 "등록된 리뷰가 없습니다."를 출력한다. (NullPointException 방지)

 

3)리뷰 출력에 페이징

 

4)숙소/편의시설/관광지 목록에 평균별점 및 리뷰 개수 출력

검색방법별로 나눠진 컨트롤러에도 전부 코드 입력 필요 도메인과 로우매퍼에 넣어버려서 필요없어졌다.

목록에서 평균별점을 출력하려면 각 항목의 contentSeq로 별점을 불러와서 계산해야 하고, hotelList를 가져오는 함수 안에서 처리해야 한다. 지금 HotelList를 가져오는 함수는 다음과 같다.

	public List<Hotel> getAllHotelList() 
	{		
		String SQL = "SELECT * FROM Hotel";
		List<Hotel> listOfHotels = template.query(SQL, new HotelRowMapper());
		
		return listOfHotels;
	}

함수 안에서 평균별점을 따로 계산해서 입력하기는 어려워보인다.

Hotel 테이블에 평균별점을 계산해놓은 컬럼을 만들고 Hotel 도메인에 평균별점 변수를 만들까?

hotel_review 테이블에 값이 입력될 때마다 컬럼이 갱신되도록 트리거를 만들면 될 것 같다.

리뷰 개수도 변수와 컬럼, 트리거를 만들어야겠다.

별점은 항목이 없으면 0개로 출력하고, 리뷰 개수도 null이면 0으로 출력한다. 그냥 컬럼을 만들 때 default 0으로 설정했다.

 

 

평균값을 계산하는 쿼리는 다음과 같다.

SELECT ROUND(AVG(rev_star)) AS avg_star FROM hotel_review GROUP BY contentSeq;

 

필요없었다...트리거에서는 group by를 사용하지 않고도 where절만으로도 그룹화해서 집계함수를 사용할 수 있다고 한다.(GPT)

DELIMITER $$
CREATE TRIGGER update_hotel_review_stats
AFTER INSERT ON hotel_review
FOR EACH ROW
BEGIN
    DECLARE review_num INT;
    DECLARE star_avg INT;
    
    -- 별점 갱신
    SELECT COUNT(*), ROUND(AVG(rev_star)) INTO review_num, star_avg 
    FROM hotel_review WHERE contentSeq = NEW.contentSeq;
    
    UPDATE Hotel
    SET review_num = review_num,
        star_avg = star_avg
    WHERE contentSeq = NEW.contentSeq;
END$$
DELIMITER ;

이렇게 group by를 사용하지 않은 트리거를 생성했고, 확인 결과 group by 없이도 집계 함수가 의도대로 잘 작동했다.

 

(1)테이블에 컬럼 추가, 트리거 작성

(2)도메인에 변수 및 getter/setter 작성

(3)RowMapper에 추가

(3)뷰 페이지에 출력 코드 작성

 

 

spot 페이지에서 별 입력이 안 됨!!!!!!

→jQuery 로드하는 스크립트 태그가 없었음

 

 

2. 리뷰 뷰 조정

 

현재 상태

 

계획

+페이징

 

1)리뷰 테이블에 컬럼 추가

- 닉네임: 세션 아이디로 user_mem 테이블에 접근해서 가져옴 ←출력할 때만 가져올지 테이블에 아예 저장해놓을지 고민됨. 일단 테이블에 저장하는 방향으로 코드 작성해봄

- 작성일시: DB에 넣을 때 자동으로 입력하는 트리거 작성 TIMESTAMP 사용(update 했을 때 변경 안 되는지 확인)

- mem_id: user_mem 테이블과 FK로 연결, NOT NULL

안정적인 뷰를 위해서 리뷰 글자수 제한도 필요하겠다

*유효성 검사: 로그인 상태여야 리뷰 작성 가능

 

(1)FK를 PK와 연결하는 이유: 인덱스

mem_nickname 컬럼으로 FK를 만들려고 하는데 다음과 같은 오류가 발생했다.

Error Code: 1822. Failed to add the foreign key constraint. Missing index for constraint 'hotel_review_ibfk_3' in the referenced table 'user_mem'

 

참조하려는 컬럼에는 인덱스가 있어야 한다. PRIMARY KEY는 만들면 자동으로 인덱스가 생성된다. 지금까지는 배운 그대로 PK만 FK로 가져왔기 때문에 몰랐다.

잠깐 깜빡해서 PK도 아니고 UNIQUE도 아닌 컬럼을 지정한 덕분에 알게 됐다...

 

 

(1)review 테이블 컬럼 추가

(2)도메인 변수 추가

(3)RowMapper setter 추가

(4)Repository sql문 변경

- Controller에서 sessionId를 가져가서 전달

(5)뷰 수정

수정했더니 뷰에서 리뷰 출력이 안 됨!!!!!!

입력은 정상적으로 됨

forEach 안에 안 넣어서 그런 거였음ㅎ;;

 

 

 

 

 

 

숙소나 관광지나 편의시설이나 코드랑 쿼리가 거의 똑같은데 하나로 통일할 수는 없을까

review service/repository를 하나로 만든 것처럼 파라미터로 조작하면 될 것 같다

식음료랑 체험은 아직 API 연결해서 데이터베이스 넣는 것만 만들었으니까 여기서 해보면 되겠다.

 

 

설명글 출력시 '-' 기준으로 끊어서 엔터

 

큰일남.......로그인 check에 파라미터로 아이디랑 비밀번호가 다 나옴..........

redirect 하니까 해결됐다ㅎ

애초에 왜 POST 방식을 안 썼나 했더니, 폼에 method 설정을 POST로 안 하고 그대로 놔둬서 GET이 돼있었다.

로그인 컨트롤러를 만들 때 폼에서 submit으로 제출하면 자동으로 POST가 된다고 생각했던 것 같다. 그런데 PostMapping으로는 매핑이 안 되니까 action으로 url을 다르게 잡고 GetMapping으로 가져갔었다. 바보같긴...

<form> 태그는 method를 지정하지 않으면 GET 방식을 사용하고, spring의 <form:form> 태그는 method를 지정하지 않아도 POST 방식으로 제출한다. 오늘은 실수에서 두 개나 배웠다...

 

 

오늘의 성과

 

 

 

 

월요일에 할 일

리뷰 update, delete 코드 작성(관리자 - member 관리처럼 파라미터로 num값 가져가서 하면 될 듯)

 

앞으로 할 일

1. 지도 API 사용해서 여행코스 만들기

- 코스간 이동 거리

- 필요 비용

- 예상 유류비

- 여행지 비용 발생시 계산해서 총액

 

2. 고속도로 휴게소 표시