본문 바로가기

Backend/Spring

Spring Boot MongoDB 연동

스프링 부트에서 몽고DB를 연동하는 방법에 대해서 알아보려고 해요.

연동은 생각보다 굉장히 쉬워요.

스프링에서 JPA를 사용해보신 분들은 API 사용에 있어서 만큼은 따로 공부할 것도 거의 없을거에요.

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

build.gradle

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

application.yml

몽고 DB의 접속 정보를 적어주세요.

여기까지하면 몽고 DB 연동은 끝났습니다.

 

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      database: tutorial

 

혹은

 

spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/tutorial

EventDoc

우선, 도큐먼트 스키마를 작성해주세요.

@Document가 몽고DB에서는 collection이 될거에요.

몽고 DB에서 collection명은 보통 복수형으로 표기합니다. 전 그냥 단수형으로 해요.

 

@Document("event")
@Getter
@Setter
public class EventDoc {

	@Id
	private String _id;
	
	private String title;
	
	private String image;
	
}

 

자! 여기까지는 공통으로 작업해줘야 할 내용이구요.

Spring Boot에서 MongoDB에 실제로 접근하여 기능을 수행할 API를 사용하는 방법은 크게 2가지에요.

하나는 MongoRepository<T, ID>를 상속받은 인터페이스를 사용하는 방법이 있구요.

또 하나는 MongoTemplate 빈을 사용하는 방법이죠.

CASE 1) MongoTemplate

 

우선, MongoTemplate을 이용해서 작성해볼거에요.

기능 3개를 아주 간단하게 만들어볼게요.

1. ID로 이벤트 정보 조회하기

2. 제목으로 이벤트 리스트 검색하기

3. 이벤트 등록하기

 

@Service
public class EventService {
	
	@Autowired
	private MongoTemplate mongoTemplate;
	
	public EventDoc getEvent(String _id) {
		EventDoc event = mongoTemplate.findById(_id, EventDoc.class);
		return Optional.ofNullable(event).orElseThrow(() -> new RestException(HttpStatus.NOT_FOUND, "Not found event"));
	}
	
	public List<EventDoc> getEventList(String title) {
		Query query = new Query().addCriteria(Criteria.where("title").is(title));
		return mongoTemplate.find(query, EventDoc.class);
	}
	
	public EventDoc insertEvent(EventDoc body) { 
		return mongoTemplate.insert(body);
	}

}

 

MongoTemplate의 메서드를 확인해볼게요.

 

CASE 2) EventRepo extends MongoRepository<T, ID>

우선, MongoRepository<T, ID>를 상속받은 인터페이스를 하나 만들어주세요.

인터페이스를 활용해서 우리는 이제 미리 만들어진 API를 사용할 수 있어요.

@Document가 추가될 때마다 인터페이스를 추가해줘야해요.

 

public interface EventRepo extends MongoRepository<EventDoc, String> {
	
	List<EventDoc> findByTitle(String title);

}

 

로직을 작성해볼게요.

위의 MongoTemplate을 사용할 때와 한 번 비교도 해주세요.

 

@Service
public class EventService {
	
	@Autowired
	private EventRepo eventRepo;
	
	public EventDoc getEvent(String _id) {
		return eventRepo.findById(_id).orElseThrow(() -> new RestException(HttpStatus.NOT_FOUND, "Not found event"));
	}
	
	public List<EventDoc> getEventList(String title) {
		return eventRepo.findByTitle(title);
	}
	
	public EventDoc insertEvent(EventDoc body) { 
		return eventRepo.insert(body);
	}

}

 

EventRepo의 메서드를 확인해볼게요.

대충 이름만 봐도 메서드가 어떤 기능을 수행하는지 알 수 있을거에요.

잘 골라서 사용하시면 됩니다. 기본적인 API는 요게 다에요.

추가적으로 EventRepo 안에 findByTitle과 같이 커스텀한 메서드를 작성하여 API를 직접 생성할 수 있어요.

 

 

 

MongoRepository를 이용하면?

  • Optional 클래스를 리턴하여 비즈니스 소스 단에서 예외 처리하기 용이 (코드 간결)
  • 인터페이스 별도 파일에 메소드로 API를 제작하여 사용

MongoTemplate를 이용하면?

  • @Document만 관리하면 됨
  • 쿼리를 비즈니스 소스 단에서 생성함

잘 선택해서 사용하시면 되구요.

어차피 @Document는 공통적으로 사용하기 때문에 둘다 병행해서 쓰셔도 되긴 해요.

 

지금까지 MongoDB를 연동하고 API가 제대로 동작하는지 간단하게 테스트했습니다.