웹사이트 검색

스프링 부트 몽고DB


Spring Boot MongoDB 예제에 오신 것을 환영합니다. Spring Boot는 스프링 프로젝트를 빠르게 스핀하는 가장 쉬운 방법이며 MongoDB는 가장 널리 사용되는 NoSQL 데이터베이스입니다. Spring을 MongoDB 데이터베이스와 통합하는 방법을 살펴보겠습니다.

스프링 부트 몽고DB

Spring Boot 및 MongoDB 데이터베이스와 함께 작동하려면 다음 API가 필요합니다.

  • 스프링 데이터 몽고DB
  • 스프링 부트

MongoDB 데이터베이스에 연결할 수 있는 두 가지 방법인 MongoRepositoryMongoTemplate이 있습니다. 우리는 하나의 API가 다른 API보다 무엇을 제공하는지, 언제 사용 사례에 대해 API 중 하나를 선택해야 하는지 설정하려고 노력할 것입니다. 프로젝트를 빠르게 설정하기 위해 Spring Initializr 도구를 사용할 것입니다. 자, 시작하겠습니다.

Spring Boot MongoDB 프로젝트 설정

메이븐 종속성

도구로 이미 설정을 완료했지만 수동으로 설정하려는 경우 이 프로젝트에 Maven 빌드 시스템을 사용하며 사용한 종속 항목은 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.journaldev.spring</groupId>
	<artifactId>spring-boot-mongodb</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-boot-mongodb</name>
	<description>Spring Boot MongoDB Example</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Maven Central에서 Spring Boot용 안정 버전을 사용해야 합니다.

스프링 부트 MongoDB 모델 클래스

간단한 모델 클래스 User.java가 있습니다.

package com.journaldev.bootifulmongodb.model;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public class User {

	@Id
	private String userId;
	private String name;
	private Date creationDate = new Date();
	private Map<String, String> userSettings = new HashMap<>();

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getCreationDate() {
		return creationDate;
	}

	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

	public Map<String, String> getUserSettings() {
		return userSettings;
	}

	public void setUserSettings(Map<String, String> userSettings) {
		this.userSettings = userSettings;
	}
}

스프링 부트 MongoDB API

앱에는 다음과 같은 기능과 데이터베이스 상호 작용이 있습니다.

  • 모든 사용자 가져오기
  • ID가 있는 사용자 가져오기
  • 사용자 설정 가져오기
  • 지도에서 특정 키 가져오기
  • 사용자 설정 추가/업데이트

스프링 데이터 MongoDB - MongoRepository

이제 Spring Data MongoDB 리포지토리를 사용하여 데이터에 액세스합니다. Spring Data MongoRepository는 쉽게 플러그인하여 사용할 수 있는 공통 기능을 제공합니다. Repository 인터페이스를 정의해 보겠습니다.

package com.journaldev.bootifulmongodb.dal;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.journaldev.bootifulmongodb.model.User;

@Repository
public interface UserRepository extends MongoRepository<User, String> {
}

MongoDB 속성 정의

컨트롤러를 배치하기 전에 MongoDB의 로컬 인스턴스와 연결하는 것이 중요합니다. 이를 위해 Spring Boot 속성을 사용할 것입니다.

#Local MongoDB config
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.username=root
spring.data.mongodb.password=root
spring.data.mongodb.database=user_db
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost

# App config
server.port=8102
spring.application.name=BootMongo
server.context-path=/user

따라서 앱은 포트 8102에서 실행되고 제공된 자격 증명을 사용하여 로컬 mongoDB 인스턴스에 연결됩니다. 인증이 활성화되지 않은 로컬 인스턴스가 있는 경우 구성의 처음 세 줄만 제거하면 됩니다.

스프링 컨트롤러 정의

마지막으로 Controller 클래스를 만드는 단계로 이동하겠습니다.

package com.journaldev.bootifulmongodb.controller;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RestController;

import com.journaldev.bootifulmongodb.dal.UserRepository;
import com.journaldev.bootifulmongodb.model.User;

@RestController
@RequestMapping(value = "/")
public class UserController {

	private final Logger LOG = LoggerFactory.getLogger(getClass());

	private final UserRepository userRepository;

	public UserController(UserRepository userRepository) {
		this.userRepository = userRepository;
	}
}

우리는 방금 리포지토리 인터페이스 종속성을 Autowired했으며 다음에 이것을 사용할 것입니다.

API 정의

우리가 언급한 기능에 대해 이제 API를 만들고 내부적으로 Spring Data MongoRepository API를 사용할 userRepository 종속성에 액세스할 것입니다. Spring Data가 모든 작업을 수행하므로 인터페이스에 데이터베이스 상호 작용 코드를 작성할 필요가 없습니다.

모든 사용자 가져오기

@RequestMapping(value = "", method = RequestMethod.GET)
public List<User> getAllUsers() {
	LOG.info("Getting all users.");
	return userRepository.findAll();
}

findAll()은 Spring Data MongoRepository가 내부적으로 제공하는 메소드일 뿐입니다.

ID로 사용자 가져오기

이제 ID가 있는 특정 사용자를 가져오겠습니다.

@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User getUser(@PathVariable String userId) {
	LOG.info("Getting user with ID: {}.", userId);
	return userRepository.findOne(userId);
}

findOne()은 Spring Data MongoRepository가 ID로 Object를 얻기 위해 내부적으로 제공하는 메소드일 뿐입니다.

새 사용자 추가

아래 함수에 새 사용자를 추가할 것입니다.

@RequestMapping(value = "/create", method = RequestMethod.POST)
public User addNewUsers(@RequestBody User user) {
	LOG.info("Saving user.");
	return userRepository.save(user);
}

사용자 설정 가져오기

이제 샘플 데이터를 DB에 추가했으므로 그 중 일부를 추출해 보도록 하겠습니다.

@RequestMapping(value = "/settings/{userId}", method = RequestMethod.GET)
public Object getAllUserSettings(@PathVariable String userId) {
	User user = userRepository.findOne(userId);
	if (user != null) {
		return user.getUserSettings();
	} else {
		return "User not found.";
	}
}

특정 사용자 설정 가져오기

@RequestMapping(value = "/settings/{userId}/{key}", method = RequestMethod.GET)
public String getUserSetting(@PathVariable String userId, @PathVariable String key) {
	User user = userRepository.findOne(userId);
	if (user != null) {
		return user.getUserSettings().get(key);
	} else {
		return "User not found.";
	}
}

위의 쿼리에서 사용자 개체를 얻은 다음 완전한 설정 맵(1000개의 개체를 포함할 수 있음)을 추출하고 최종적으로 자체 값을 얻었습니다. 이는 직접 API로 사용할 때 Spring 데이터 쿼리의 단점입니다.

새 사용자 설정 추가

기존 사용자에게 일부 데이터를 추가해 보겠습니다.

@RequestMapping(value = "/settings/{userId}/{key}/{value}", method = RequestMethod.GET)
public String addUserSetting(@PathVariable String userId, @PathVariable String key, @PathVariable String value) {
	User user = userRepository.findOne(userId);
	if (user != null) {
		user.getUserSettings().put(key, value);
		userRepository.save(user);
		return "Key added";
	} else {
		return "User not found.";
	}
}

우리가 작성한 모든 코드를 통해 리포지토리 인터페이스를 정의하고 종속성을 자동 연결하는 것 외에 데이터베이스에 액세스하기 위해 한 줄의 코드를 작성할 필요가 없다는 것이 분명합니다. 이것은 Spring Data MongoRepository API가 우리에게 제공하는 용이함이지만 몇 가지 단점도 있습니다. MongoTemplate 버전도 정의했을 때 이를 자세히 설명하겠습니다. 그것도 시작합시다.

스프링 데이터 MongoDB - MongoTemplate

여기에서 MongoTemplate 데이터베이스 쿼리를 정의할 것입니다. MongoTemplate을 사용하면 쿼리 대상과 결과에 포함되는 데이터를 훨씬 더 세밀하게 제어할 수 있습니다.

DAL 인터페이스 정의

데이터베이스 액세스 계층에서 계약을 제공하기 위해 Spring Data 내장 메서드처럼 작동하는 인터페이스를 정의하는 것으로 시작합니다.

package com.journaldev.bootifulmongodb.dal;

import java.util.List;

import com.journaldev.bootifulmongodb.model.User;

public interface UserDAL {

	List<User> getAllUsers();

	User getUserById(String userId);

	User addNewUser(User user);

	Object getAllUserSettings(String userId);

	String getUserSetting(String userId, String key);

	String addUserSetting(String userId, String key, String value);
}

DAL 인터페이스 구현

계속해서 이러한 메서드를 정의해 보겠습니다.

package com.journaldev.bootifulmongodb.dal;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import com.journaldev.bootifulmongodb.model.User;

@Repository
public class UserDALImpl implements UserDAL {

	@Autowired
	private MongoTemplate mongoTemplate;

	@Override
	public List<User> getAllUsers() {
		return mongoTemplate.findAll(User.class);
	}

	@Override
	public User getUserById(String userId) {
		Query query = new Query();
		query.addCriteria(Criteria.where("userId").is(userId));
		return mongoTemplate.findOne(query, User.class);
	}

	@Override
	public User addNewUser(User user) {
		mongoTemplate.save(user);
		// Now, user object will contain the ID as well
		return user;
	}

	@Override
	public Object getAllUserSettings(String userId) {
		Query query = new Query();
		query.addCriteria(Criteria.where("userId").is(userId));
		User user = mongoTemplate.findOne(query, User.class);
		return user != null ? user.getUserSettings() : "User not found.";
	}

	@Override
	public String getUserSetting(String userId, String key) {
		Query query = new Query();
		query.fields().include("userSettings");
		query.addCriteria(Criteria.where("userId").is(userId).andOperator(Criteria.where("userSettings." + key).exists(true)));
		User user = mongoTemplate.findOne(query, User.class);
		return user != null ? user.getUserSettings().get(key) : "Not found.";
	}

	@Override
	public String addUserSetting(String userId, String key, String value) {
		Query query = new Query();
		query.addCriteria(Criteria.where("userId").is(userId));
		User user = mongoTemplate.findOne(query, User.class);
		if (user != null) {
			user.getUserSettings().put(key, value);
			mongoTemplate.save(user);
			return "Key added.";
		} else {
			return "User not found.";
		}
	}
}

위 클래스의 메서드 구현은 MongoTemplate 종속성을 사용하고 있습니다. getUserById(...) 메서드가 사용자를 가져오는 방법을 확인하세요. 쿼리를 구성하고 필수 매개변수를 전달했습니다. 더 흥미로운 것은 getUserSetting 쿼리입니다. 위에서 일어난 일을 이해합시다.

  • 동일성을 확인하는 기준으로 쿼리를 구성했습니다.
  • include 메소드는 결과가 DB에서 추출될 때 포함되어야 하는 필드 이름을 포함합니다. 즉, 이 경우 userSettings 키가 추출되어 필요하지 않은 가져올 많은 데이터를 저장합니다.
  • 또한 사용자와 맵 키를 모두 쿼리했습니다. 하나라도 없으면 필요한 키를 찾을 수 없다는 빈 데이터를 반환합니다. 이렇게 하면 필요한 키가 없는 경우 사용자 개체를 전혀 가져오지 않아도 됩니다.

스프링 데이터 MongoDB 테스트 실행

단일 명령을 사용하여 간단하게 이 앱을 실행할 수 있습니다.

mvn spring-boot:run

앱이 실행되면 다음 API를 사용하여 새 사용자를 저장할 수 있습니다.

https://localhost:8102/user/create

이는 POST 요청이므로 JSON 데이터도 전송합니다.

{
  "name" : "Shubham",
  "userSettings" : {
    "bike" : "pulsar"
  }
}

Mongo 응답 자체를 반환하면 다음과 같은 결과를 얻게 됩니다.

{
  "userId": "5a5f28cc3178058b0fafe1dd",
  "name": "Shubham",
  "creationDate": 1516165830856,
  "userSettings": {
    "bike" : "pulsar"
  }
}
https://localhost:8102/user/

우리는 다음과 같은 것을 돌려받을 것입니다:

[
  {
    "userId": "5a5f28cc3178058b0fafe1dd",
    "name": "Shubham",
    "creationDate": 1516165830856,
    "userSettings": {
      "bike" : "pulsar"
    }
  }
]
//define Data Access Layer object
private final UserDAL userDAL;

//initialize DAL object via constructor autowiring
public UserController(UserRepository userRepository, UserDAL userDAL) {
	this.userRepository = userRepository;
	this.userDAL = userDAL;
}

//change method implementation to use DAL and hence MongoTemplate
@RequestMapping(value = "/settings/{userId}", method = RequestMethod.GET)
public Object getAllUserSettings(@PathVariable String userId) {
    User user = userRepository.findOne(userId);
    if (user != null) {
        return userDAL.getAllUserSettings(userId);
    } else {
        return "User not found.";
    }
}

//change method implementation to use DAL and hence MongoTemplate
@RequestMapping(value = "/settings/{userId}/{key}", method = RequestMethod.GET)
public String getUserSetting(
        @PathVariable String userId, @PathVariable String key) {
    return userDAL.getUserSetting(userId, key);
}

MongoTemplate 대 MongoRepository

  • MongoTemplate은 데이터 쿼리 및 데이터베이스에서 가져올 데이터와 관련하여 훨씬 더 많은 제어 기능을 제공합니다.
  • Spring Data 저장소는 데이터를 가져오는 방법에 대한 편리한 전망을 제공합니다.
  • MongoTemplate은 데이터베이스에 따라 다릅니다. 이것이 의미하는 바는 Spring Data 리포지토리를 사용하면 MySQL 또는 Neo4J 또는 다른 것에 대해 다른 Spring Data 리포지토리를 사용하기만 하면 다른 데이터베이스로 쉽게 전환할 수 있다는 것입니다. MongoTemplate에서는 불가능합니다.

스프링 부트 MongoDB 요약

이 레슨에서 우리는 MongoTemplate이 Spring Data 리포지토리에 대한 더 많은 제어를 제공하지만 더 깊은 쿼리가 관련될 때 약간 복잡할 수 있는 방법을 살펴봤습니다. 따라서 아이디어를 개발할 때 무엇을 선택해야 하는지는 전적으로 귀하의 결정입니다. 아래에 의견을 남겨주세요. 아래 링크에서 소스코드를 다운로드 받습니다. 제공된 앱을 실행하기 전에 MongoDB 자격 증명을 변경했는지 확인하십시오.

Spring Boot MongoDB 예제 프로젝트 다운로드