[Springboot / MongoDB] Springboot와 MongoDB 연결하기

HeavyJ·2023년 6월 11일
2

자바/스프링부트

목록 보기
14/17
post-thumbnail

저는 평소에 데이터베이스로는 관계형 데이터베이스인 MySQL을 사용했습니다.

하지만, 크롤링한 데이터를 저장해야 하는 상황이 발생했기 때문에 NoSQL인 MongoDB를 사용하기로 했습니다.

구글링을 하면서 Springboot와 MongoDB를 연동한 최신글이 생각보다 없는 것 같아서 직접 연결해보고 처음 시도해보는 사람들에게 도움이 됐으면 하는 바람에 글을 작성하게 됐습니다!


그러면 MongoDB의 특징과 제가 MongoDB를 선택한 이유에 대해서 알아보겠습니다.

MongoDB 특징

MongoDB의 특징에 대해서 알아보겠습니다.

  • 도큐먼트 지향
    MongoDB는 도큐먼트 지향적인 데이터베이스입니다.
    JSON 형태로 데이터를 관리하는 구조입니다.
    객체 지향적으로 DB를 저장할 수 있다는 장점이 있습니다.

  • 스키마less
    MongoDB는 스키마나 테이블과 같은 정형적인 구조에 데이터를 저장하는 것이 아니라 비정형 데이터를 저장할때 주로 사용합니다.
    여기서 테이블과 같은 역할을 하는 컬렉션이 존재하는데 컬렉션에도 저장 규칙이 따로 존재하지 않습니다.

  • 비관계형 DB
    MongoDB에는 관계의 개념이 없습니다. 따라서, 조인 연산을 지원하지 않습니다.

  • 트랜잭션 지원 X
    관계형 DB와 다르게 트랜잭션을 지원하지 않습니다..
    따라서 Commit이나 Rollback의 개념이 존재하지 않습니다.

MongoDB 선택한 이유

제가 MongoDB를 선택한 이유는 특징 중 도큐먼트 지향과 스키마가 없다는 점 때문입니다.

크롤링을 해야 하는 웹사이트가 여러개일 경우 사이트마다 데이터 표시 구조가 다르고 수집할 수 있는 데이터도 차이가 있습니다.

만약, 관계형 DB를 사용할 경우에는 이렇게 사이트마다 테이블을 따로 만들어야 할 수도 있습니다. 하지만, MongoDB를 사용하면 테이블이 없는 Schema-less 구조이기 때문에 하나의 컬렉션 혹은 하나의 데이터베이스에서 처리가 가능하다고 생각했습니다.

그리고 도큐먼트 지향 DB이기 때문에 데이터 저장이 관계형 DB보다 수월하다고 생각했습니다. 객체지향적으로 데이터를 저장할 수 있다는 점이 크롤링한 데이터를 저장할 때 수월하다고 느꼈습니다.

MongoDB 연결 방법

MongoDB 생성 방법

아래의 블로그를 참고하시면 될 것 같습니다. 설명이 잘 되어 있네요!
https://naman-develop.tistory.com/172



MongoDB를 연결하는 방법은 크게 3가지로 보시면 될 것 같습니다.

  • Application에서 연결하는 방법
  • MongoDB Compass(MongoDB GUI)를 다운 받아서 프로그램 형태로 사용
  • 터미널(Shell)에서 사용하기

Application에 연결하는 방법은 저의 경우에는 Springboot에 연결했는데 이 부분은 글의 후반부에 다루겠습니다.

MongoDB Compass

먼저 Compass를 다운받는 방법입니다.

Compass가 없다면 다운을 받아줍니다.
저는 Mac을 사용하기 때문에 macOS로 다운 받습니다.

다운이 완료됐다면 응용프로그램을 열고 해당 url을 입력해줍니다.

기왕이면 Save & Connect를 해야 한 번만 입력하면 되기 때문에 편할것 같네요

그러면 이렇게 Compass에서 원하는 데이터베이스로 접속이 가능해집니다.

저는 내부 Database를 하나 더 만들어줬는데요 원하는 Collection 이름과 함께 입력하시면 됩니다!

Collection은 RDBMS에서 테이블과 유사하다고 생각하시면 됩니다

Collection을 만들었다면 DATA를 한 번 추가해보겠습니다.

ADD DATA를 클릭한 뒤 데이터를 입력합니다. 임시 데이터를 넣을 것이기 때문에 Document를 사람이라고 가정하고 name과 age 값을 넣어보겠습니다.

이렇게 위의 필터 기능을 사용해서 검색도 가능합니다.

MongoDB Shell

이번에는 CUI(명령 줄 인터페이스) 형태인 Shell로 MongoDB에 접속해보겠습니다.

macOS 기준으로 brew package manager를 사용해서 mongosh를 설치해줍니다.

brew install mongosh

설치가 완료되면 명령어에 밑에 내용을 복붙해줍니다.

mongosh "mongodb+srv://pushpin.lgan0wm.mongodb.net" --apiVersion 1 --username 유저이름

use database 명령어를 입력해줘서 해당 database로 이동해줍니다.

Atlas atlas-8ucwc0-shard-0 [primary] test> use 데이터베이스 이름

db.컬렉션이름.find()를 하면 입력되어 있는 document가 모두 검색이 됩니다.

db.컬렉션이름.find()

find함수에 필터를 걸어서 원하는 데이터를 검색할 수도 있습니다.

db.컬렉션이름.find({"name":"woo"})


MongoDB와 Springboot 연결하기 (Spring Data MongoDB)

그러면 Application에서 MongoDB를 사용해보겠습니다.

Atlas의 Connect에 들어가서 Drivers를 클릭해줍니다.

저는 Springboot의 환경설정 파일을 사용할 것이기 때문에 따로 클래스를 만들어줄 필요없이 yml을 이용할 것입니다.

먼저, build.gradle에 의존성을 입력해줍니다.

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

이후에 application.yml 파일에 connectionString의 데이터를 입력해줍니다.

spring:
  data:
    mongodb:
      uri: mongodb+srv://user:<password>@pushpin.lgan0wm.mongodb.net/<database이름>?retryWrites=true&w=majority

(참고)
다른 블로그나 레퍼런스에서는 이런식으로 입력한 경우도 있었는데, 저는 오히려 이렇게 입력하면 작동이 안 됐고 uri 형태로 입력해야 제대로 작동이 됐습니다!

spring:
	data:
    	mongdb:
        	host:
            port:
            user:
            password:

마지막으로 Spring Data MongoDB를 사용하기 위해 Application 클래스에 어노테이션을 넣어줍니다.

@EnableMongoRepositories

혹시나 이렇게 했을 때 오류가 발생한다면 basePackage 설정도 추가로 해보세요!

MongoDB의 컬렉션에 사용할 클래스를 하나 만들어줍니다. (엔티티와 유사)

CrawlingInfo.class

@Document(collection = "interpark") // 실제 몽고 DB 컬렉션 이름 
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class CrawlingInfo {
    @Id
    private String id;
    private String name;
    private Long age;
}

이 클래스를 사용해서 해당하는 이름에 맞는지 검색하는 로직을 완성해보겠습니다!
Controller


Message message = new Message();

        CrawlingInfo crawlingInfo = crawlingService.getCrawlingInfoByName(title);

        message.setStatus(StatusEnum.OK);
        message.setMessage("해당하는 이름을 가져옵니다.");
        message.setData(crawlingInfo);

        return new ResponseEntity(message, HttpStatus.OK);

Service

@Service
@RequiredArgsConstructor
public class CrawlingService {
    private final CrawlingRepository crawlingRepository;
    private final MongoTemplate mongoTemplate;

    public CrawlingInfo getCrawlingInfoByName(String name) {

        CrawlingInfo crawlingInfo = crawlingRepository.findCrawlingInfoByName(name);

        return crawlingInfo;
    }
}

Repository


@Repository
public interface CrawlingRepository extends MongoRepository<CrawlingInfo, String>{
	    CrawlingInfo findCrawlingInfoByName(String name);

}

Repsository도 JPARepository를 사용할 때와 유사한 형태로 사용하면 됩니다.
Repository를 만들어준뒤 그 뒤에 필요한 조건에 따라 쿼리 메소드를 선언해주면 됩니다.

Spring Data MongoDB를 사용하기 위해서는 Repository를 쓰는 방법과 MongoTemplate을 쓰는 방법 2가지가 있습니다.

  • MongoTemplate
  • MongoRepository 상속받은 Repository 사용

MongoTemplate을 쓰는 방법은 Criteria(쿼리를 만들어주는 클래스)와 함께 사용할 수도 있고 기본적으로 제공하는 메소드를 사용하여 기본적인 CRUD 기능을 수행할 수 있습니다.


하지만, 저는 다음과 같은 3가지 이유 때문에 Repository를 사용했습니다.

  • 복잡한 쿼리문일 시 가독성 높이기
  • 쿼리 메소드로 개발자 편의성 증대
  • Querydsl 도입 고려

복잡한 쿼리문이 필요할 경우에는 결국에는 Repository 추상화가 필요하다고 판단했고 필드명을 사용하는 쿼리 메소드를 사용할 수 있다는 장점도 있었기 때문에 Repository를 만들어서 MongoRepository를 상속받아 사용했습니다. 또한 이후에 더 복잡한 로직을 만들어야 할 경우 Querydsl 도입도 고려했습니다.


결과

로직을 실행하면 해당하는 이름에 맞는 데이터를 가져오는 것을 확인할 수 있습니다.

지금은 찾기 로직만 사용해봤는데 이후에 insert, update, delete까지 같이 사용해보면서 MongoDB에 대한 감을 익히는게 중요할 것 같습니다.

아무래도 익숙하게 쓰던 관계형 데이터베이스가 아니기 때문에 많이 써보면서 숙련도를 올려야 할 것 같네요👍

profile
There are no two words in the English language more harmful than “good job”.

1개의 댓글

comment-user-thumbnail
2024년 3월 22일

CUI(명령 줄 인터페이스) -> CLI 오타있어요.

답글 달기