-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: message entity, repository 구현 #424
base: BE/develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.yigongil.backend.domain.message; | ||
|
||
import com.yigongil.backend.domain.BaseEntity; | ||
import com.yigongil.backend.domain.member.Member; | ||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.GenerationType; | ||
import javax.persistence.Id; | ||
import javax.persistence.JoinColumn; | ||
import javax.persistence.ManyToOne; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Entity | ||
public class Message extends BaseEntity { | ||
|
||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Id | ||
private Long id; | ||
|
||
@ManyToOne | ||
@JoinColumn(nullable = false, updatable = false) | ||
private Member sender; | ||
|
||
@ManyToOne | ||
@JoinColumn(nullable = false, updatable = false) | ||
private Member receiver; | ||
|
||
@Column(nullable = false) | ||
private String content; | ||
|
||
protected Message() { | ||
} | ||
|
||
@Builder | ||
public Message(Long id, Member sender, Member receiver, String content) { | ||
this.id = id; | ||
this.sender = sender; | ||
this.receiver = receiver; | ||
this.content = content; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Message{" + | ||
"id=" + id + | ||
", sender=" + sender + | ||
", receiver=" + receiver + | ||
", content='" + content + '\'' + | ||
'}'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.yigongil.backend.domain.message; | ||
|
||
public interface MessageListDto { | ||
|
||
String getContent(); | ||
|
||
String getCreatedAt(); | ||
|
||
boolean getIsMine(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.yigongil.backend.domain.message; | ||
|
||
import com.yigongil.backend.domain.member.Member; | ||
import java.util.List; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.domain.Slice; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.Repository; | ||
|
||
public interface MessageRepository extends Repository<Message, Long> { | ||
|
||
Message save(Message message); | ||
|
||
@Query(""" | ||
select distinct m.sender as sender, m.receiver as receiver | ||
from Message m | ||
where m.sender = :member or m.receiver = :member | ||
""") | ||
List<MessageSenderReceiverDto> findBySenderOrReceiver(Member member); | ||
|
||
@Query(""" | ||
select m.content as content, m.createdAt as createdAt, | ||
case when m.sender.id = :memberId then true else false end as isMine | ||
from Message m | ||
where (m.sender.id = :memberId and m.receiver.id = :opponentId) | ||
or (m.sender.id = :opponentId and m.receiver.id = :memberId) | ||
order by m.id desc | ||
""") | ||
Slice<MessageListDto> findAllMessageByMemberAndPaging(Long memberId, Long opponentId, Pageable pageable); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.yigongil.backend.domain.message; | ||
|
||
import com.yigongil.backend.domain.member.Member; | ||
|
||
public interface MessageSenderReceiverDto { | ||
|
||
Member getSender(); | ||
|
||
Member getReceiver(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package com.yigongil.backend.domain.message; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertAll; | ||
|
||
import com.yigongil.backend.config.JpaConfig; | ||
import com.yigongil.backend.domain.member.Member; | ||
import com.yigongil.backend.domain.member.MemberRepository; | ||
import com.yigongil.backend.fixture.MemberFixture; | ||
import java.util.List; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; | ||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; | ||
import org.springframework.context.annotation.Import; | ||
import org.springframework.data.domain.PageRequest; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.domain.Slice; | ||
|
||
@Import(JpaConfig.class) | ||
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 안쓰면 어떻게 되나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 부분과 아래 Application.yml을 변경한 부분과 연관관계가 있는 것 같은데 저도 궁금하네요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
@DataJpaTest | ||
class MessageRepositoryTest { | ||
|
||
@Autowired | ||
private MessageRepository messageRepository; | ||
|
||
@Autowired | ||
private MemberRepository memberRepository; | ||
|
||
private Member 김진우; | ||
private Member 노이만; | ||
private Pageable pageable; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
김진우 = memberRepository.save(MemberFixture.김진우.toMember()); | ||
노이만 = memberRepository.save(MemberFixture.폰노이만.toMember()); | ||
pageable = PageRequest.of(0, 10); | ||
} | ||
|
||
@Test | ||
void 메시지를_주고받은_상대들을_조회하는_쿼리() { | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 노이만, 김진우, "Hello, world!")); | ||
|
||
List<MessageSenderReceiverDto> result = messageRepository.findBySenderOrReceiver(김진우); | ||
|
||
assertThat(result).hasSize(2); | ||
} | ||
|
||
@Test | ||
void 메시지를_주고받은_상대들을_조회하는_쿼리2() { | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 노이만, 김진우, "Hello, world!")); | ||
|
||
List<MessageSenderReceiverDto> result = messageRepository.findBySenderOrReceiver(김진우); | ||
|
||
assertThat(result).hasSize(2); | ||
} | ||
|
||
@Test | ||
void 메시지를_주고받은_상대들을_조회하는_쿼리3() { | ||
Member 파울러 = memberRepository.save(MemberFixture.마틴파울러.toMemberWithoutId()); | ||
|
||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 노이만, 김진우, "Hello, world!")); | ||
messageRepository.save(new Message(null, 파울러, 김진우, "Hello, world!")); | ||
|
||
List<MessageSenderReceiverDto> result = messageRepository.findBySenderOrReceiver(김진우); | ||
|
||
assertThat(result).hasSize(3); | ||
} | ||
|
||
@Test | ||
void 메시지를_주고받은_상대들을_조회하는_쿼리4() { | ||
Member 파울러 = memberRepository.save(MemberFixture.마틴파울러.toMemberWithoutId()); | ||
|
||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 노이만, 김진우, "Hello, world!")); | ||
messageRepository.save(new Message(null, 파울러, 김진우, "Hello, world!")); | ||
messageRepository.save(new Message(null, 노이만, 파울러, "Hello, world!")); | ||
|
||
List<MessageSenderReceiverDto> result = messageRepository.findBySenderOrReceiver(김진우); | ||
|
||
assertThat(result).hasSize(3); | ||
} | ||
|
||
@Test | ||
void 주고받은_쪽지를_정렬한다() { | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
messageRepository.save(new Message(null, 노이만, 김진우, "Hello, world!")); | ||
|
||
Slice<MessageListDto> result = messageRepository.findAllMessageByMemberAndPaging(김진우.getId(), 노이만.getId(), pageable); | ||
|
||
assertAll( | ||
() -> assertThat(result).hasSize(3), | ||
() -> assertThat(result.getContent().get(0).getIsMine()).isFalse(), | ||
() -> assertThat(result.getContent().get(1).getIsMine()).isTrue(), | ||
() -> assertThat(result.getContent().get(2).getIsMine()).isTrue() | ||
); | ||
} | ||
|
||
@Test | ||
void 주고받은_쪽지를_페이징한다() { | ||
for (int i = 0; i < 11; i++) { | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
} | ||
|
||
Slice<MessageListDto> result = messageRepository.findAllMessageByMemberAndPaging(김진우.getId(), 노이만.getId(), pageable); | ||
|
||
assertAll( | ||
() -> assertThat(result).hasSize(pageable.getPageSize()), | ||
() -> assertThat(result.hasNext()).isTrue() | ||
); | ||
} | ||
|
||
@Test | ||
void 주고받은_쪽지를_페이징한다2() { | ||
for (int i = 0; i < 9; i++) { | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
} | ||
|
||
Slice<MessageListDto> result = messageRepository.findAllMessageByMemberAndPaging(김진우.getId(), 노이만.getId(), pageable); | ||
|
||
assertAll( | ||
() -> assertThat(result).hasSize(9), | ||
() -> assertThat(result.hasNext()).isFalse(), | ||
() -> assertThat(result).map(MessageListDto::getIsMine).doesNotContain(false) | ||
); | ||
} | ||
|
||
@Test | ||
void 파라미터_순서를_바꿔서_주고받은_쪽지를_페이징한다() { | ||
for (int i = 0; i < 9; i++) { | ||
messageRepository.save(new Message(null, 김진우, 노이만, "Hello, world!")); | ||
} | ||
|
||
Slice<MessageListDto> result = messageRepository.findAllMessageByMemberAndPaging(노이만.getId(), 김진우.getId(), pageable); | ||
|
||
assertAll( | ||
() -> assertThat(result).hasSize(9), | ||
() -> assertThat(result.hasNext()).isFalse(), | ||
() -> assertThat(result).map(MessageListDto::getIsMine).doesNotContain(true) | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
별게 다있네요ㅋㅋㅋ 배워갑니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
우리가 예전에 우려했던 대로 Pageable을 사용하면 새로운 dm을 보낼 때 과거의 메시지가 중복돼서 보이는 문제가 있을 수 있겠네요..
하지만 이런 앱의 dm에서 중복된 메시지가 등장하는 것이 유저에게 얼마나 불편함을 불러일으킬지도 미지수긴 합니다ㅎㅎ
이건 다른 분들의 의견도 들어보고 싶네요!