본문 바로가기
WEB/Spring

[Spring] MongoDB 연동하고 데이터 관리하기

by 정권이 내 2023. 12. 13.

[Spring] MongoDB 연동하고 데이터 관리하기

 

MongoDB는 NoSQL 데이터베이스중 하나로 여러 기업에서 사용하고 있을정도로 성능이 검증된 데이터베이스입니다. MongoDB의 기본적인 구조는 데이터베이스, 컬렉션, 도큐먼트 단위로 관리됩니다.

일반적인 RDBMS와 비교해보면 다음과 같습니다.

MongoDB RDBMS (Oracle, Mysql...)
Database Database
Collection Table
Document Row

 

Spring Boot 기본 설정

 

의존성 추가

mongodb, spring web을 사용하기위해 의존성을 추가합니다.

implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'

 

mongoDB 접속정보 추가

mongoDB를 설치한 환경에 맞게 application.yml 파일에 접속정보를 작성합니다.

server:
  port: 9090

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      authentication-database: admin
      database: my-database
      username: ksr930
      password: 1234

 

예제 코드 만들기

mongoDB에 user 컬렉션을 만들었고 name, age 필드를 가진 도큐먼트를 저장하기 위해서 각 클래스의 역할은 다음과 같습니다.

  • MongoDBTestModel : 컬렉션의 필드 구조를 정의
  • MongoDBTestRepository: MongoDB 라이브러리인 MongoRepository 을 상속받은 인터페이스 생성
  • MongoDBTestService: save, insert 기능을 구현하여 Repository 와 연결
  • MongoDBTestController: 웹으로부터 URL로 요청을 받아 Service에 연결

 

MongoDBTestModel.java

@Document어노테이션을 추가하고 collection에 MongoDB에서 생성한 컬렉션 이름인 "user"를 지정합니다.

@Getter
@Setter
@Document(collection = "user")
public class MongoDBTestModel {

    private String name;
    private int age;
}

 

MongoDBTestRepository.java

mongoDB 라이브러리 인터페이스인 MongoRepository를 상속받고 name값으로 MongoDB user 컬렉션에 저장된 데이터를 찾기위해findByName 이라는 추상메서드를 생성합니다.

public interface MongoDBTestRepository extends MongoRepository<MongoDBTestModel, String> {
    MongoDBTestModel findByName(String name);
}

 

MongoDBTestService.java

MongoDBTestRepository 객체를 호출하여 데이터 저장, 조회 기능을 수행하는 서비스입니다.

  • selectUser: user컬렉션에서 조건에 맞는 도큐먼트를 찾아서 Json String 형태로 반환
  • insertUser: MongoDBTestModel 객체를 생성하여 user컬렉션에 도큐먼트를 저장하는 기능, 만약 동일한 name을 가진 도큐먼트가 있다면 해당 도큐먼트를 업데이트.
@Slf4j
@Component
public class MongoDBTestService {

    @Autowired
    MongoDBTestRepository mongoDBTestRepository;

    public String selectUser(String name) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            if (mongoDBTestRepository.findByName(name) == null) {
                log.info("[Service] user name : {} not exist!!", name);
                return String.format("user name : %s not exist!!", name);
            } else {
                return objectMapper.writeValueAsString(mongoDBTestRepository.findByName(name));
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return "ERROR";
        }
    }

    public void saveUser(String name, int age) {

        MongoDBTestModel mongoDBTestModel = new MongoDBTestModel();
        mongoDBTestModel.setName(name);
        mongoDBTestModel.setAge(age);

        if (mongoDBTestRepository.findByName(name) != null) {
            log.info("[Service][update] name is already exist!!");
            mongoDBTestModel.setId(mongoDBTestRepository.findByName(name).getId());
        } else {
            log.info("[Service][insert] New name received!!");
        }

        mongoDBTestRepository.save(mongoDBTestModel);
    }
}

 

MongoDBTestController.java

RestAPI를 요청받는 url은 각각 select, insert & update 서비스와 연결됩니다.

@Slf4j
@RestController
@RequestMapping(path = "/mongo")
public class MongoDBTestController {

    @Autowired
    MongoDBTestService mongoDBTestService;

    @GetMapping(value = "/find")
    public String findUserData(@RequestParam String name) {
        return mongoDBTestService.selectUser(name);
    }

    @GetMapping(value = "/save")
    public String saveUserData(@RequestParam String name, @RequestParam int age) {
        log.info("[Controller][Recv] name : {}, age : {}", name, age);
        mongoDBTestService.saveUser(name, age);

        return mongoDBTestService.selectUser(name);
    }
}

 

MongoDB Compass 설치

MongoDBCompass 는 SQLDeveloper 같은 mongoDB 전용 DB Browser 프로그램 입니다. 테스트할때 데이터가 정상적으로 추가되거나 변경되는지 편리하게 확인할수 있습니다.

mongoDB 공식 사이트에서 MongoDB Compass 를 받으면 되고 저는 미설치 버전인 zip 버전으로 압축을 풀어서 실행했습니다.

 

프로그램을 실행하고 New Connection을 눌러서 application.yml 에 작성했던 접속정보를 url 형식으로 입력하여 연결하면 됩니다.

mongodb://[USERNAME]:[PASSWORD]@[IPADDRESS]:27017/[database]

img

 

테스트를 하기위해 test라는 Database를 만들고 user 라는 이름의 컬렉션도 같이 만들었습니다.

img

 

동작 설명

데이터 처리기능을 테스트 하기 위해 웹브라우저나 Postman 으로 http://localhost:9090/mongo/save/?name=ksl930&age=30 RestAPI 요청을 전송하면 컨트롤러에서 수신하고 Service 단의 saveUser 메서드로 RequestParam 값들을 전달하게 됩니다.

@GetMapping(value = "/save")
public String saveUserData(@RequestParam String name, @RequestParam int age) {
    mongoDBTestService.saveUser(name, age);

    return mongoDBTestService.selectUser(name);
}

 

saveUser 메서드에서 MongoDBTestModel의 인스턴스를 만들고 name, age 값을 할당합니다. findByName 메서드에서 MongoDB에 동일한 name값을 가지는 도큐먼트 유무에 따라서 update 혹은 insert 작업을 합니다.

public void saveUser(String name, int age) {

    MongoDBTestModel mongoDBTestModel = new MongoDBTestModel();
    mongoDBTestModel.setName(name);
    mongoDBTestModel.setAge(age);

    if (mongoDBTestRepository.findByName(name) != null)
        mongoDBTestModel.setId(mongoDBTestRepository.findByName(name).getId());

    mongoDBTestRepository.save(mongoDBTestModel);
}

 

saveUser의 동작이 끝난후에는 Service 단의 selectUser 메서드를 호출하여 레포지터리의 findByName 메서드로

저장한 데이터를 화면에 출력합니다.

public String selectUser(String name) {
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        return objectMapper.writeValueAsString(mongoDBTestRepository.findByName(name));
    } catch (JsonProcessingException e) {
        e.printStackTrace();
        return "ERROR";
    }
}

 

insert 테스트

Spring Boot 서버를 실행하고 데이터 저장을 위해 RestAPI를 요청 해보겠습니다.

http://localhost:9090/mongo/save/?name=ksl930&age=30

img

 

저장한 결과가 json 데이터 형식으로 표출되었고 서버의 로그는 다음과 같습니다.

INFO xxx.controller.MongoDBTestController	: [Controller][Recv] name : ksl930, age : 30
INFO xxx.service.MongoDBTestService		: [Service][insert] New name received!!

 

이제 MongoDB Compass를 확인하여 실제로 데이터가 저장되었는지 확인 해보겠습니다.

img

 

update 테스트

insert 테스트 할때와 같은 name을 전달하고 age 값만 변경하여 update 기능을 확인 해보겠습니다.

http://localhost:9090/mongo/save/?name=ksl930&age=99

img

INFO xxx.controller.MongoDBTestController	: [Controller][Recv] name : ksl930, age : 99
INFO xxx.service.MongoDBTestService		: [Service][update] name is already exist!!

 

MongoDB에도 age가 99로 변경되어 저장된것을 확인할수 있습니다.

img

 

select 테스트

현재 user 컬렉션에 없는 name을 찾는 상황을 확인 해보겠습니다.

http://localhost:9090/mongo/find/?name=tistory

img

 

예상대로 현재 user 컬렉션에 tistory 라는 name을 가진 데이터가 없다는 의미의 내용을 출력하고 있습니다.

INFO xxx.service.MongoDBTestService		: [Service] user name : tistory not exist!!

 

연관 포스팅

반응형

댓글