inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

웹소켓/STOMP 채팅서비스(spring, vue, redis)

이전메시지조회

쿼리, jpa 질문 있습니다.

해결된 질문

152

hxcva1

작성한 질문수 8

0

16:00 초에 보면 채팅 메세지를 가져오는데 이때 멤버 정보도 같이 가져오는 것 같다고 보여지는데 findByRoomOrderByCreatedTimeAsc를 호출할때 쿼리가 어떻게 날아가는지 이해가 잘 안되서 질문드립니다. 메세지의 개수마다 멤버 테이블에 join해서 가져오는게 맞는걸까요?

spring-boot websocket stomp-websocket pubsub vue-3

답변 2

0

bradkim

findByRoomOrderByCreatedTimeAsc 쿼리는 select * from chat_message where room_id=? order by created_time asc; 이러한 raw쿼리와 같습니다.

이러한 쿼리를 통해 ChatMessage객체를 List형태로 조회하게 되는데, ChatMessage객체 안에는 Member객체를 가지고 있어서, 메시지마다 member정보를 꺼낼수 있게 되는 거라고 보시면되겠습니다.

0

hxcva1

멤버테이블과 조인되지 않는데 member 정보를 가져올 수 있는걸까요?

0

bradkim

Message객체에 ManyToOne으로 Member가 잡혀있어서 Member정보를 가져 올수 있습니다! join걸린것과 같다고 보시면되겠습니다.

0

hxcva1

그럼 메세지 리스트를 가져올 때 멤버당 1번만 정보를 가져오는 건지 아니면 메세지마다 멤버의 정보를 가져오는건지 궁금합니다

0

bradkim

지금 현재 코드로서는 메시지마다 member를 가지고 오고 있습니다. 성능최적화를 위해서는 fetch join을 통해서 한꺼번에 member객체를 가져오는 것이 좋을것 같습니다. 우리 수업에서는 채팅아키텍처에 집중하기 위해서 성능부분들은 많이 배제하고 넘어갔습니다.

0

hxcva1

db설계를 변경해서 풀어낼 수 있는 방법이 있을까요?

0

bradkim

DB설계변경으로 풀어낼방법은 message테이블이 작성자 정보를 넣어놔야 하는데, 그건 추천드리지 않습니다. 정규화가 되지 않아, 추후 member정보가 변경됐을때 message테이블에 데이터가 갱신되지 않는 문제등 여러 문제가 발생할 가능성이 있어보입니다.

0

hxcva1

결론적으로 모든 메세지에 대해서 작정자 정보를 가져와야하는데 이것을 fetch join으로 한번에 가져올지 아니면 메세지마다 하나씩 가져오는지의 차이라고 이해하면 될까요?

0

bradkim

넵 맞습니다. 효율성을 위해서는추후 프로젝트에서는 fetch join을 사용하심이 좋아보입니다.

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. hxcva1님.

채팅 메세지와 멤버 정보를 함께 가져오는 경우, findByRoomOrderByCreatedTimeAsc 메서드는 JPA를 통해 데이터베이스에서 데이터를 조회할 때 주로 사용됩니다. 이러한 메서드는 내부적으로 JPQL(Querydsl과 비슷한 동작 방식) 또는 네이티브 SQL 쿼리를 사용하여 필요한 데이터를 가져옵니다.

여기서 findByRoomOrderByCreatedTimeAsc는 특정 채팅 방(room)에 있는 메세지를 시간 순으로 정렬하여 가져오는 용도로 보입니다. 이 쿼리를 통해 반환되는 메세지 리스트는 각 메세지에 연결된 멤버 정보도 함께 가져오기 위해 @ManyToOne 또는 @Join 자연적인 관계 설정을 포함하고 있을 수 있습니다.

쿼리 작동 방식:
- JPA는 해당 메서드를 실행하면서 메세지 엔티티와 멤버 엔티티 간의 관계가 설정되어 있다면, JPQL 쿼리로 자동으로 조인(Join)하여 관련 데이터를 가져옵니다.
- 예를 들어, 메세지 엔티티에서 @ManyToOne 어노테이션으로 멤버 엔티티를 참조하고 있다면, JPA는 관련 멤버 데이터를 자동으로 가져와서 객체에 주입합니다.
- 따라서 결과적으로는 각 메세지마다 연결된 멤버 데이터를 조인하여 한 번의 쿼리로 모두 가져오는 방식이 됩니다.

성능 측면에서 이러한 JOIN 쿼리는 데이터가 많을 경우 속도가 느려질 수 있으므로, 필요에 따라 페치 조인 또는 배치(fetch size) 옵션을 사용하여 최적화할 수 있습니다. 이는 데이터베이스와 네트워크 부하를 줄이는 데 도움을 줄 수 있습니다.

아래의 유사한 질문과 답변을 통해 추가적인 정보를 얻으실 수 있습니다:
- Spring Data JPA 상에서의 JOIN 사용법에 대한 논의 - JPA 조인 및 페치 전략 설명 포함

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

ERD 질문

0

54

2

StompHandler 관한 질문

0

80

2

리프레시 토큰은 알아서 구현하면 되는건가요??

0

79

2

cors, csrf 직접 구현

0

64

1

JWT 필터구현

0

98

2

강의 잘듣고 있습니다. 혹시 다음 강의 계획은 없으신가요?

0

57

1

STOMP 동작 과정 질문

0

48

1

chain.doFilter()

0

45

1

자바 21로 소스 작성해도 되나요?

0

60

2

메시지 브로커 선택에 관한 질문

0

65

2

WebSocket과 Spring Security 질문

0

81

2

추가 커스텀 구현 질문 있습니다.

0

59

2

connect와 동시에 구독하는데 구독 검증이 꼭 필요한가요?

0

97

2

저도 동일한 질문인데

0

78

3

token이 필요한 엔드포인트에 의도적으로 토큰 누락시 대처

0

67

2

수업자료가 왜 다 나눠져있나요?

0

78

2

메시지 전송 시 검증

0

61

2

JWT 생성 시 subject 설정에 대한 질문

0

157

3

StompHandler 질문 있습니다.

0

82

2

앱 서비스일 경우

0

83

2

웹소켓 서버 재배포시 고려해야 할 상황 질문

0

107

2

배포 오류 질문

0

123

2

/connect 경로에 대한 토큰 검증의 필요성

0

77

1

JwtTokenProvider 작성중 오류 발생으로 문의드립니다.

0

96

2