이번에 만들 것은 MongoDB를 활용한 CRUD RestfulAPI이다.
몽고DB는 NoSQL DB의 한 종류로, humongous의 줄임말이다. 직역하면 매우 큰 DB 라는 뜻이다.
몽고DB는 NoSQL 중 Document DB 타입의 데이터베이스로, 그냥 간단하게 설명하면 데이터가 JSON/XML 같은 형태로 저장되는 DB라는 의미이다.
예시를 보자면 아래와 같이 저장된다고 볼 수 있다.
몽고디비의 데이터는 Document라고 부르고, 이 Document의 집합 즉 테이블을 Collection이라고 부른다. Collection의 집합은 DB로, 이 부분은 RDB와 같다.
NoSQL 답게 몽고디비는 RDB보다 훨씬 빠르지만, 일관성을 유지하기에는 힘이 들 수 있다.
그러면 이제 개발을 시작할 것인데, 사실 전체적인 틀은 MariaDB와 별반 다를 바 없다.
일단 application.properties이다.
프로그램 형태도 마찬가지로 Domain-Repository-Service-Controller 순으로 작성한다.
데이터베이스, 작동 방식도 사실 MariaDB의 코드를 그대로 복사해와 변수명, 함수명 정도만 바꾸어주었다.
다만 Domain의 경우 MariaDB는 @Table 어노테이션을 사용했지만 MongoDB는 @Document 어노테이션을 사용했다.
그리고 MongoDB의 PK는 id라는 이름으로 사용되어야 하며, 타입은 원래는 ObjectID여야 하지만 실습에서는 편의상 String으로 대체했다.
MongoDomain.java
package kr.co.opensource.mongo;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Document(collection="test_col")
@JsonInclude(JsonInclude.Include.NON_NULL)
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class MongoDomain {
@Id
private String id;
private String val;
}
Repository는 MongoDB 전용 Repository를 사용해야 한다.
MongoRepositories.java
package kr.co.opensource.mongo;
import java.util.Optional;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@EnableMongoRepositories
public interface MongoRepositories extends MongoRepository<MongoDomain, ObjectId>{
public Optional<MongoDomain> findById(String id);
public void deleteById(String id);
}
Service와 Controller는 MariaDB와 완전히 동일하다.
MongoService.java
package kr.co.opensource.mongo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.co.opensource.CommonCode;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class MongoService {
@Autowired MongoRepositories repo;
public int save(MongoDomain domain) {
log.info("MongoService.save init : {}", domain.toString());
if(repo.findById(domain.getId()).orElse(null) != null) {
//이미 존재하는 데이터
log.info("MongoService.save data already exists : {}", domain.getId());
return CommonCode.EXCEPTION;
}
try {
repo.save(domain);
}
catch(Exception e) {
//쿼리 과정 중 에러 발생
log.error("MongoService.save some internal error occured : {}", e.getMessage());
return CommonCode.ERROR;
}
return CommonCode.SUCCESS;
}
public int update(MongoDomain domain) {
log.info("MongoService.update init : {}", domain.toString());
MongoDomain tmpDomain = repo.findById(domain.getId()).orElse(null);
if(tmpDomain == null) {
//존재하지 않는 데이터
log.info("MongoService.update data not exists : {}", domain.getId());
return CommonCode.EXCEPTION;
}
try {
tmpDomain.setVal(domain.getVal());
repo.save(tmpDomain);
}
catch(Exception e) {
//쿼리 과정 중 에러 발생
log.error("MongoService.update some internal error occured : {}", e.getMessage());
return CommonCode.ERROR;
}
return CommonCode.SUCCESS;
}
public int delete(String key) {
log.info("MongoService.delete init : {}", key);
if(repo.findById(key).orElse(null) == null) {
//존재하지 않는 데이터
log.info("MongoService.delete data not exists : {}", key);
return CommonCode.EXCEPTION;
}
try {
repo.deleteById(key);
}
catch(Exception e) {
log.error("MongoService.delete some internal error occured : {}", e.getMessage());
return CommonCode.ERROR;
}
return CommonCode.SUCCESS;
}
public MongoDomain find(String key) {
log.info("MongoService.find init : {}", key);
return repo.findById(key).orElse(null);
}
public List<MongoDomain> findAll() {
log.info("MongoService.findAll init");
Iterator<MongoDomain> domainItr = repo.findAll().iterator();
List<MongoDomain> domainList = new ArrayList();
while(domainItr.hasNext()) {
domainList.add(domainItr.next());
}
return domainList;
}
}
MongoRestController.java
package kr.co.opensource.mongo;
import java.nio.charset.Charset;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.co.opensource.CommonCode;
import kr.co.opensource.ResponseMessage;
import kr.co.opensource.ResponseVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class MongoRestController {
@Autowired MongoService service;
@RequestMapping(value={"/mongo","/mongo/{key}"}, method= {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
public @ResponseBody ResponseEntity<ResponseVO> controller(HttpServletRequest req,
@PathVariable(value="key", required=false) String key,
@RequestBody(required=false) MongoDomain domain) {
log.info("MongoRestController.controller init http: {}", req.getMethod());
ResponseVO msg = new ResponseVO();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
String method = req.getMethod();
if(method.equals("GET")) {
if(key == null) {
log.info("MongoRestController.controller get all data");
List<MongoDomain> mongoDomainList = service.findAll();
msg.setStatus(HttpStatus.OK);
msg.setMessage(ResponseMessage.OK);
msg.setData(mongoDomainList);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
}
log.info("MongoRestController.controller get one data : {}", key);
MongoDomain returnDomain = service.find(key);
if(returnDomain == null) {
log.warn("MongoRestController.controller not exists data : {}", key);
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.NOT_EXISTS);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
msg.setStatus(HttpStatus.OK);
msg.setMessage(ResponseMessage.OK);
msg.setData(returnDomain);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
}
else if(method.equals("POST")) {
log.info("MongoRestController.controller save data : {}", domain);
if(domain == null) {
log.error("MongoRestController.controller required parameter not exists");
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.NOT_EXISTS_BODY);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
int result = service.save(domain);
if(result == CommonCode.EXCEPTION) {
//이미 존재하는 데이터
log.warn("MongoRestController.controller already exist data : {}", domain);
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.EXISTS);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
else if(result == CommonCode.ERROR) {
//쿼리 실패
log.warn("MongoRestController.controller some interner error exists");
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.INTERNAL_ERROR);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
else {
//성공
log.info("MongoRestController.controller successfully saved data : {}", domain);
msg.setStatus(HttpStatus.CREATED);
msg.setMessage(ResponseMessage.CREATED);
msg.setData(domain);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.CREATED);
}
}
else if(method.equals("PUT")) {
log.info("MongoRestController.controller update data : {}", key);
if(key == null) {
log.warn("MongoRestController.controller required parameter not exists");
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.NOT_EXISTS_KEY);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
int result = service.update(domain);
if(result == CommonCode.EXCEPTION) {
log.info("MongoRestController.controller not exists data : {}", domain);
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.EXISTS);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
else if(result == CommonCode.ERROR) {
//쿼리 실패
log.warn("MongoRestController.controller some interner error exists");
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.INTERNAL_ERROR);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
else {
//성공
log.info("MongoRestController.controller successfully updated data : {}", key);
msg.setStatus(HttpStatus.OK);
msg.setMessage(ResponseMessage.OK);
msg.setData(domain);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
}
}
else if(method.equals("DELETE")) {
log.info("MongoRestController.controller update data : {}", key);
if(key == null) {
log.warn("MongoRestController.controller required parameter not exists");
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.NOT_EXISTS_KEY);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
int result = service.delete(key);
if(result == CommonCode.EXCEPTION) {
log.warn("MongoRestController.controller not exists data : {}", key);
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.NOT_EXISTS);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
else if(result == CommonCode.ERROR) {
log.warn("MongoRestController.controller some interner error exists");
msg.setStatus(HttpStatus.BAD_REQUEST);
msg.setMessage(ResponseMessage.INTERNAL_ERROR);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
}
else {
//성공
log.info("MongoRestController.controller successfully deleted data : {}", key);
msg.setStatus(HttpStatus.OK);
msg.setMessage(ResponseMessage.OK);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
}
}
//여기까지 올일은 사실상 없음.
//그냥 return null 하기 싫어서 기재.
msg.setStatus(HttpStatus.METHOD_NOT_ALLOWED);
msg.setMessage(ResponseMessage.NOT_ALLOWED_METHD);
msg.setData(null);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.METHOD_NOT_ALLOWED);
}
}
이렇게 코딩을 끝마치고 마찬가지로 포스트맨을 사용하면 테스트를 해볼 수 있다.
1) 등록
2) 수정
3) 조회
4) 삭제
'실습 > 리눅스 서버 + 스프링 부트' 카테고리의 다른 글
06. RabbitMQ_Con&Pro (0) | 2021.05.30 |
---|---|
05. RestfulAPI_Redis CRUD (0) | 2021.05.23 |
03. RestfulAPI_MariaDB (0) | 2021.05.19 |
02. 윈도우 세팅 및 프로젝트 생성 (0) | 2021.05.19 |
01. 리눅스 서버 세팅 (0) | 2021.05.05 |