[SpringBoot] WebSocket, STOMP - 실시간 채팅②, Entity, domain

SihoonCho·2023년 3월 25일
1
post-thumbnail

※ 읽기에 앞서


본 시리즈는 작성자의 이해와 경험을 바탕으로 실습 위주의 설명을 기반으로 작성되었습니다.
실습 위주의 이해를 목표로 하기 때문에 다소 과장이 많고 생략된 부분이 많을 수 있습니다.
따라서, 이론적으로 미흡한 부분이 있을 수 있는 점에 대해 유의하시기 바랍니다.

또한, SpringBoot 기반의 Backend 위주의 설명을 포함하고 있으니
Frontend 에 대해서는 별도로 참고자료를 찾아보시기를 권장드립니다.


📌 Base Entity


날짜/시간과 관련된 기본 Entity를 먼저 구현합니다.
-> created_date, updated_date


📖 BaseTime.java


@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTime {
    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    @Column(updatable = true)
    private LocalDateTime updatedDate;
}

날짜 데이터는 거의 대부분의 데이터에 포함되는 공통 속성이므로
추후 여러 데이터에서 상속받아 사용할 수 있도록 별도의 Class로 구현하였습니다.

추상화 클래스를 사용하였으며, lombokJPA의 어노테이션을 사용하여 구현되었습니다.


📖 MainApplication.java


@EnableJpaAuditing
@SpringBootApplication
public class ProjectNameApplication {
	public static void main(String[] args) {
		SpringApplication.run(ProjectNameApplication.class, args);
	}
}

데이터베이스에서 날짜/시간 정보를 정상적으로 자동생성되게 하려면
가장 메인이되는 Java Class에 JPA 어노테이션을 추가해주어야 합니다.

스프링부트 프로젝트로 생성하였다면 보통은
메인 클래스가 프로젝트명Application.java로 되어 있고
@SpringBootApplication 어노테이션이 기본으로 작성되어있습니다.

우리는 여기에 추가로 @EnableJpaAuditing 어노테이션을 추가합니다.


📌 Core Entity


domain package에 해당하는 Entity에 대해 구현하겠습니다.

├── config
│   └── WebSocketConfig.java
├── domain
│   ├── ChatRoom.java
│   └── ChatMessage.java
├── dto
│   ├── ChatRoomRequestDto.java
│   ├── ChatRoomResponseDto.java
│   ├── ChatMessageRequestDto.java
│   └── ChatMessageResponseDto.java
├── repository
│   ├── ChatRoomRepository.java
│   └── ChatMessageRepository.java
├── service
│   ├── ChatRoomService.java
│   └── ChatMessageService.java
├── controller
│   ├── ChatRoomRestController.java
│   ├── ChatMessageRestController.java
│   └── LiveChatController.java

필요한 EntityChatRoom.java, ChatMessage.java 입니다.


📖 ChatRoom.java


@NoArgsConstructor
@Getter
@Entity
public class ChatRoom extends BaseTime {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String roomName;

    @OneToMany(mappedBy = "chatRoom", cascade = CascadeType.REMOVE)
    private List<ChatMessage> chatMessageList;

    @Builder
    public ChatRoom(String roomName) {
        this.roomName = roomName;
    }

    public Long update(ChatRoomRequestDto requestDto) {
        this.roomName = requestDto.getRoomName();
        return this.id;
    }
}

ChatRoom.java 특징

ChatRoom.javaChatMessage.java1:N의 관계로 연결되어있습니다.
BaseTime.java를 상속받아 updated_date, created_date가 생략되어있습니다.
채팅방 이름이 변경될 수 있기 때문에 update 기능을 미리 추가하였습니다.

ChatRoom.java 필드

  • id: PK(Primary Key), 각 채팅방 구분
  • roomName: 채팅방 이름
  • chatMessageList: 해당 채팅방에서 기록된 모든 채팅

이해가 어렵다면 '게시글과 댓글'의 관계를 생각하시면 됩니다.
주로 예제에서는 Post.javaComment.java의 관계로 나타냈을 겁니다.
여기서 ChatRoom.javaPost.java에 해당합니다.


📖 ChatMessage.java


@NoArgsConstructor
@Getter
@Entity
public class ChatMessage extends BaseTime {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String sender;
    private String message;

    @ManyToOne
    private ChatRoom chatRoom;

    @Builder
    public ChatMessage(String sender, String message, ChatRoom chatRoom) {
        this.sender = sender;
        this.message = message;
        this.chatRoom = chatRoom;
    }
}

ChatMessage.java 특징

ChatRoom.javaChatMessage.java1:N의 관계로 연결되어있습니다.
BaseTime.java를 상속받아 updated_date, created_date가 생략되어있습니다.

ChatMessage.java 필드

  • id: PK(Primary Key), 각 메세지 구분
  • sender: 메세지 발신자
  • message: 메세지 내용
  • chatRoom: 해당 메세지와 연결된 채팅방

이해가 어렵다면 '게시글과 댓글'의 관계를 생각하시면 됩니다.
주로 예제에서는 Post.javaComment.java의 관계로 나타냈을 겁니다.
여기서 ChatMessage.javaComment.java에 해당합니다.


📌 결론


실시간 채팅에 Database를 적용하기 위한 기초 작업이 끝났습니다.
사실 Database 적용을 위한 작업은, 기초 예제인 게시글 Entity인
Post.java를 만드는 것과 크게 다르지 않습니다.

다음 시간에는 필요한 속성만 추출하여 전달하기 위한 데이터임과 동시에
실시간으로 Front와 주고받을 데이터인 DTO를 생성하겠습니다.


본 시리즈는 SpringBoot 기반의 WebSocket, STOMP 실시간 채팅기능 구현을 목표로
최근 트렌드와 함께 WebSocket, STOMP의 정형화된 기초개념을 정립하기 위해 작성되었습니다.

WebSocket을 찾아 헤매는 모든 이들에게 이 글을 바칩니다.


본 시리즈는 작성자의 이해와 경험을 바탕으로 실습 위주의 설명을 기반으로 작성되었습니다.
실습 위주의 이해를 목표로 하기 때문에 다소 과장이 많고 생략된 부분이 많을 수 있습니다.
따라서, 이론적으로 미흡한 부분이 있을 수 있는 점에 대해 유의하시기 바랍니다.

또한, SpringBoot 기반의 Backend 위주의 설명을 포함하고 있으니
Frontend 에 대해서는 별도로 참고자료를 찾아보시기를 권장드립니다.
profile
꾸준히 노력하는 개발자

0개의 댓글