Atlas의 MongoDB FLUX사용해보자
gradle 설정
//Mongo DB
implementation ("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
yml 설정
spring:
data:
mongodb:
uri:
uri는 엔드포인트 넣어주자.
Entity 설정
package com.example.gameproject.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.annotation.Id;
import java.time.LocalDateTime;
@Data
@Document(collection = "chat")
public class Chat_E {
@Id
private String id;
private String msg;
@Indexed
private String sender;
@Indexed
private String receiver;
private LocalDateTime createAt;
}
Repository 설
package com.example.gameproject.repository;
import com.example.gameproject.entity.Chat_E;
import com.example.gameproject.entity.Game_E;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.data.mongodb.repository.Tailable;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
@Repository
public interface MongDBChetRepository extends ReactiveMongoRepository<Chat_E, String> {
@Tailable//커서를 안닫고 계속 유지한다.
@Query("{sender:?0,receiver:?1}")
Flux<Chat_E> mfindBySender(String sender, String receiver); //reponse 를 유지하며 데이터를 계속 흘려보내기
}
Service 설정
package com.example.gameproject.service;
import com.example.gameproject.entity.Chat_E;
import com.example.gameproject.repository.MongDBChetRepository;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Service
@RequiredArgsConstructor
public class ChatService {
private final MongDBChetRepository mongoDBRepository;
public Mono<Chat_E> createChat(Chat_E chatE) {
return mongoDBRepository.save(chatE);
}
public Mono<Chat_E> updateChat(String Chat_EId, Chat_E updatedChat_E) {
return mongoDBRepository.findById(Chat_EId)
.flatMap(existingChat_E -> {
existingChat_E.setCreateAt(updatedChat_E.getCreateAt());
existingChat_E.setSender(updatedChat_E.getReceiver());
return mongoDBRepository.save(existingChat_E);
});
}
public Flux<Chat_E> findAllChats() {
return mongoDBRepository.findAll();
}
public Mono<Void> deleteChat(String Chat_EId) {
return mongoDBRepository.deleteById(Chat_EId);
}
}
Controller 설정
package com.example.gameproject.controller;
import com.example.gameproject.entity.Chat_E;
import com.example.gameproject.repository.MongDBChetRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;
import java.time.LocalDateTime;
@RestController
@RequiredArgsConstructor
public class ChatController {
private final MongDBChetRepository mongDBChetRepository;
@GetMapping(value = "/sender/{sender}/receiver/{receiver}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) //계속 유지됨
public Flux<Chat_E> getMsg(@PathVariable String sender, @PathVariable String receiver){
return mongDBChetRepository.mfindBySender(sender, receiver).subscribeOn(Schedulers.boundedElastic());
}
@PostMapping("/chat") //계속 유지됨
public Mono<Chat_E> setMsg(@RequestBody Chat_E chatE){
chatE.setCreateAt(LocalDateTime.now());
return mongDBChetRepository.save(chatE);
}
}
이제 PostMan으로 신호를 줘보자
return값을 보니 정상적으로 저장되었다.
http://localhost:8080/sender/asdd2t557@gmail.com/receiver/cos
이 URL로 검색하면 된다.
그전에 버퍼 크기를 먼저 설정해줘야한다.
MongoDB를 SSH로 접속해주자
db.chat.drop() // 기존 chat 컬렉션 삭제
db.createCollection("chat", { capped: true, size: 100000, max: 1000 }) // 새로운 chat 컬렉션 생성
위 명령을 쳐준뒤에 다시 http://localhost:8080/sender/asdd2t557@gmail.com/receiver/cos 로 접속해본다.
만약 위처럼 한글이 깨진다면 아래를 추가해주자
server:
servlet:
encoding:
charset: UTF-8
enabled: ture
force: true