일정 관리 기능을 구현하는 것이 주목적이지만 메신저 기능을 구현하고 싶어서 새로운 테이블을 하나 만들었다.
▷ 메시지 테이블
CREATE TABLE MESSAGE(
MES_NO NUMBER(10) PRIMARY KEY,
MES_CON VARCHAR2(1000 CHAR) NOT NULL,
WDATE DATE DEFAULT SYSDATE,
READ_CHECK VARCHAR2(1 CHAR) DEFAULT 'N',
SEND_ID VARCHAR2(20 CHAR) NOT NULL,
RECV_ID VARCHAR2(20 CHAR) NOT NULL,
CONSTRAINT FK_SEND_ID FOREIGN KEY(SEND_ID) REFERENCES MEMBER(ID)
ON DELETE CASCADE , // 보낸 사람이 탈퇴하면 메시지도 자동으로 삭제되기 위해 추가
CONSTRAINT FK_RECV_ID FOREIGN KEY(RECV_ID) REFERENCES MEMBER(ID)
ON DELETE CASCADE // 받는 사람이 탈퇴하면 메시지도 자동으로 삭제되기 위해 추가
);
▷ Message.java
import lombok.*;
import java.sql.Date;
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Message {
private int mes_no;
private String mes_con;
private Date wdate;
private String read_check;
private String send_id;
private String recv_id;
private String isshow;
}
메시지 테이블과 동일하게 VO 클래스를 작성해주고 데이터를 가져오기 위해 쿼리문을 작성하고 조건에 맞게 가져올 수 있도록 변수를 넘겨받도록 했다.
▷MessageMapper.xml
<select id="selectMessages" parameterType="com.todo.Hiplanner.vo.Message" resultType="com.todo.Hiplanner.vo.Message">
select
mes_no, mes_con, read_check, send_id, recv_id
from
message
where
recv_id=#{recv_id} and isshow='Y'
ORDER BY
wdate desc
</select>
#{recv_id}에는 session에 id라는 이름으로 저장되어 있는 값을 가져와서 넣어줄 것이다.
▷MessageController.java
@GetMapping("/{id}")
public ModelAndView getMessages(Message message, ModelAndView mv, HttpSession session){
message.setRecv_id((String)session.getAttribute("id"));
List<Message> messageList = messageService.selectMessages(message);
mv.addObject("messageList",messageList);
mv.setViewName("/message/message");
return mv;
}
가져온 데이터가 여러 개일 것이므로 List타입의 messageList에 가져온 데이터를 넣어준다. 그리고 그 messageList를 View에 뿌려주면 누군가 나에게 보낸 메시지를 가져올 수 있게 되는 것이다. 작성한 로직에는 문제가 없다. 그러면 서버를 직접 띄워서 정말로 View에 잘 뿌려주는지 확인해보자.
그런데 메시지 리스트에 의도한 대로 데이터를 뿌려주지 못하고 있다. 분명히 테스트를 했을 때는 DB에 있는 개수를 제대로 가지고 왔는데 무슨 문제가 있는지 알아보기 위해 디버깅 모드로 전환해서 원인을 찾아보기로 했다.
그랬더니 session에 저장된 값도 잘 가지고 오고 messageList의 size도 2개로 잘 가져오고 있는데 All elements are null이라는 구문과 함께 모든 컬럼들의 값을 null로 가지고 오고 있다. '분명히 개수도 맞게 가져오는데 컬럼만 null 상태로 가져오는 건 뭐지?'라는 반응과 함께 에러를 해결하기 위한 기나긴 여정이 시작됐다.
먼저 All elements are null을 키워드로 해결 방법을 찾아보았지만 원하는 해결 방법을 찾지 못했다. 해결 방법도 못 찾으니 작업에 진전이 안 생겨서 그냥 포기할까 했다. 하지만 오기가 생겨서 계속된 검색을 끝에 해결 방안을 찾았다.
DB 테이블을 생성할 때 '_'(언더바)를 사용해서 컬럼 이름을 작성했고 VO 클래스를 만들 때도 '_'(언더바)를 이용해서 변수를 작성했다. VO 클래스에 언더바를 없애고 카멜 케이스로 바꿔 작성했다. 그리고 application.property에 아래와 같은 프로퍼티를 작성했다.
mybatis.configuration.map-underscore-to-camel-case=true
프로퍼티를 작성함으로써 언더바를 카멜 케이스로 변환해준다고 한다. 그래서 테이블의 컬럼명과 VO 클래스의 변수 이름이 다를 경우 해당 프로퍼티를 작성하면 정상적으로 데이터를 받아올 수 있다. 그럼 이제 View에 제대로 뿌려주는지 서버를 올려서 확인해보자.
아까와 달리 메시지 번호와 보낸 사람의 id까지 제대로 가져오는 것을 확인할 수 있다.
※ 정리
DB 테이블의 컬럼은 '_'를 사용하고 VO 클래스는 카멜 케이스로 작성했다면 application.property에 아래 프로퍼티를 추가해주자!
mybatis.configuration.map-underscore-to-camel-case=true
+ 추가
처음 VO 클래스를 작성할 때 '_'를 사용해서 변수를 만들었다. 그런데 포스팅을 하기 위해 알아보던 중 DB 테이블의 컬럼 이름과 VO 클래스의 이름이 같다면 위에서 추가한 프로퍼티가 필요 없다는 것이다.....
처음 mybatis 세팅을 할 때, 필자도 모르게 저 프로퍼티가 이미 추가되어 있었다. 그래서 컬럼 이름과 VO 클래스의 변수 이름이 같은데도 제대로 가져오지 못했던 것이다. 원인도 모르고 문제를 해결했지만 지금은 원인이 어떤 것인지 제대로 알게 되었다.
정리를 다시 해보자면
DB 테이블의 컬럼은 '_' , VO 클래스의 변수는 카멜 케이스로 작성했다면
mybatis.configuration.map-underscore-to-camel-case=true
DB 테이블의 컬럼도 '_' , VO 클래스의 변수도 '_'라면 false로 작성하자.
mybatis.configuration.map-underscore-to-camel-case=false
( Java는 원래 카멜 케이스를 많이 사용한다고 하니 이 글을 보시는 분들은 true로 프로퍼티를 작성하고 VO 클래스를 카멜 케이스를 사용하여 작성하도록 하자!)
'Hi Planner' 카테고리의 다른 글
[Hi Planner] @Builder 어노테이션 ( + 트러블 슈팅) (0) | 2022.06.01 |
---|---|
[Hi Planner] 다른 일정 조회하기. (0) | 2022.05.26 |
[Hi Planner] login 화면 (0) | 2022.05.21 |
[intelliJ + gradle + spring boot] 오라클 연동과 마이바티스 의존성 추가 (0) | 2022.05.13 |
[intelliJ + gradle + spring boot] JSP 프로젝트 시작하기 (HiPlanner) (0) | 2022.05.13 |