2024. 8. 12. 18:01ㆍFCB2O4
다시 날짜와 메시지 내용을 기준으로 메시지를 삭제하는 기능을 구현하기로 결정.
그런데 날짜를 구하고 형식을 바꾸는 메서드가 두 가지가 있음을 알았다.
DateTimeFormatter와 SimpleDateFormat인데, 그 차이를 알아보았다.
//DateTimeFormatter 와 SimpleDateFormat
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String msgAt = LocalDateTime.now().format(timeFormat);
chatLog.setMsgAt(msgAt);
SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String msgAt = timeFormat.format(new Date());
chatLog.setMsgAt(msgAt);
- 스레드 안전성:
- SimpleDateFormat은 스레드가 안전하지 않으며 멀티스레드 환경에서 주의가 필요
- DateTimeFormatter은 스레드가 안전하고, 불변 객체이므로 멀티스레드 환경에서 안전하게 사용 가능
- SimpleDateFormat은 여러 스레드가 동시에 접근하는 것에 취약함
- 사용 편의성:
- DateTimeFormatter는 java.time API의 날짜와 시간 클래스를 사용하여 더 직관적이고 유연하게 날짜와 시간을 다룰 수 있다
- SimpleDateFormat은 구식 API로, DateTimeFormatter 에 비해 다소 불편할 수 있다.
그리고 날짜 형식이 자꾸 맞지 않는 것 때문에 차라리 sendMessage 함수의 body에서 시간을 하나 더 만들어 화면에 출력할 시간과 서버에 보낼 함수를 분리 시켰다.
// 메시지 보내기
const sendMessage = () => {
if (stompClient && connected && message) {
const memberProfile = loginMember.memberProfile;
stompClient.publish({
destination: '/app/chat.send', //java 쪽의 컨트롤러(@MessageMapping)와 맞춰서 작성
body: JSON.stringify({
profile: memberProfile,
sender: loginMember.memberId,
content: message,
viewedTime: moment().format("hh:mm a"),
formattedTime : moment().format("YYYY-MM-DD HH:mm:ss")
})
});
setMessage('');
}
else if (!connected) {
console.error('연결이 안됩니다. 관리자에 문의하세요.');
}
};
viewedTime이 화면에 출력할 시간, formattedTime이 서버로 보내 DB에 저장된 시간과 대조시킬 시간이다.
그리고 메시지를 보냄과 동시에 서버측에서는 그 시간을 기록.
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String msgAt = LocalDateTime.now().format(timeFormat);
chatLog.setMsgAt(msgAt);
그리고 DTO와 DB에서 시간과 관련된 컬럼명, 변수의 자료형을 모두 String으로 변경시켰다.
따라서 DB에 넣는 xml 구문에서
<!-- 채팅 기록 DB에 넣기 -->
<insert id="recordChatMessage" parameterType="b2o4.dto.ChatLog" useGeneratedKeys="true" keyProperty="msgNo">
INSERT INTO LiveChatMessage(memberId, msgContent, msgAt) VALUES (#{memberId}, #{msgContent}, #{msgAt})
</insert>
now() -> #{msgAt}로 변경했다.
이로써 DB에 저장되는 시간의 형식은 YYYY-MM-DD HH:mm:ss
이제 프론트 쪽에서 해당 형식과 동일한 형식을 가진 시간을 이용해 대조 시켜 삭제를 진행하면 된다.
위의 formattedTime이 YYYY-MM-DD HH:mm:ss 형식을 가지고 있는 시간이므로,
<button className='deleteBtn' onClick={() => deleteMessage({ msgContent: msg.content, msgAt: msg.formattedTime })}>
X
</button>
deleteMessage 함수에 매개변수로 해당 시간을 넣고
//채팅 메시지 삭제
const deleteMessage = async ({ msgContent, msgAt }) => {
console.log("삭제할 메시지 내용:", msgContent);
console.log("삭제할 메시지 시간:", msgAt);
await axios.delete('/chat/delete', {
params: { msgContent, msgAt }
});
setMessages(messages.filter(message => !(message.content === msgContent && message.formattedTime === msgAt)));
};
이때 필터에 "!"를 왜 쓰는지 이해가 안갔는데,
filter를 사용하는 경우
조건이 true일 때: 필터에서 제외(삭제하려는 메시지).
조건이 false일 때: 필터에서 포함 (삭제되지 않아야 하는 메시지).
즉, 메시지 내용이 같고 메시지 시간이 같은 것(true)을 제외한 나머지(! 때문에 false로 변경)를 다시 리스트에 재 배열하는 것.
이를 바탕으로 실행해 보면
여기서 아이스크림과 룩셈부르크를 삭제해보면
둘 다 정상적으로 삭제 됐음을 확인
오늘은 여기까지