환영합니다. Spring Boot MongoDB 예제에 오신 것을 환영합니다. Spring Boot는 프로젝트를 빠르게 생성하는 가장 간편한 방법이며, MongoDB는 가장 인기 있는 NoSQL 데이터베이스 중 하나입니다. 이제 스프링을 MongoDB 데이터베이스와 통합하는 방법을 살펴보겠습니다.
Spring Boot MongoDB
Spring Boot와 MongoDB 데이터베이스를 사용하기 위해 다음 API가 필요합니다.
- Spring Data MongoDB
- Spring Boot
MongoDB 데이터베이스에 연결하는 데는 두 가지 접근 방식이 있습니다 – MongoRepository
와 MongoTemplate
. 각 API가 다른 API보다 어떤 기능을 제공하는지, 그리고 사용 사례에 어떤 것을 선택해야 하는지 살펴보겠습니다. 프로젝트를 빠르게 설정하기 위해 Spring Initializr 도구를 사용할 것입니다. 그럼 시작해봅시다.
Spring Boot MongoDB 프로젝트 설정
프로젝트를 빠르게 설정하기 위해 Spring Initializr 도구를 사용할 것입니다. 아래에 표시된대로 두 가지 종속성만 사용할 것입니다: 프로젝트를 다운로드하고 압축을 푼 다음, 즐겨 사용하는 IDE인 Eclipse 또는 IntelliJ IDEA에 가져오십시오.
메이븐 종속성
우리는 이미 도구를 사용하여 설정을 완료했지만, 수동으로 설정하려는 경우 이 프로젝트에는 메이븐 빌드 시스템을 사용하고 사용한 종속성은 다음과 같습니다:
<?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>
스프링 부트의 안정된 버전을 메이븐 센트럴에서 가져와 사용하십시오.
스프링 부트 몽고디비 모델 클래스
우리는 간단한 모델 클래스 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;
}
}
스프링 부트 몽고디비 API
우리 앱에서 다음과 같은 기능과 데이터베이스 상호 작용이 있을 것입니다.
- 모든 사용자 가져오기
- 특정 ID의 사용자 가져오기
- 사용자 설정 가져오기
- 맵에서 특정 키 가져오기
- 사용자 설정 추가/업데이트
Spring Data MongoDB – MongoRepository
이제 우리는 Spring Data MongoDB repository를 사용하여 데이터에 액세스할 것입니다. 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 속성 정의하기
Controller를 설계하기 전에, MongoDB의 로컬 인스턴스와 연결하는 것이 중요합니다. 이를 위해 Spring Boot 속성을 사용할 것입니다.
# 로컬 MongoDB 설정
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
# 앱 설정
server.port=8102
spring.application.name=BootMongo
server.context-path=/user
따라서, 앱은 8102 포트에서 실행되고 제공된 자격 증명으로 로컬 mongoDB 인스턴스에 연결됩니다. 인증이 활성화되지 않은 로컬 인스턴스가 있는 경우 구성의 첫 세 줄을 제거하기만 하면 됩니다.
Spring Controller 정의하기
마지막으로 우리의 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를 만들고 userRepository 종속성에 접근할 것입니다. 이것은 내부적으로 Spring Data MongoRepository API를 사용할 것입니다. 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로 객체를 가져 오기 위해 내부적으로 제공하는 메서드입니다.
새로운 사용자 추가
아래 기능에 새로운 사용자를 추가 할 것입니다.
@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.";
}
}
위의 쿼리에서 볼 수 있듯이 사용자 개체를 가져 왔다가 완전한 설정 맵(수천 개의 개체가 포함 될 수 있음)을 추출하고 최종적으로 자체 값을 가져 왔습니다. 이것은 우리가 API를 직접 사용할 때 Spring Data 쿼리의 단점입니다.
새로운 사용자 설정 추가
@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
버전을 정의한 후에 자세히 다루겠습니다. 그럼 시작해 보겠습니다.
Spring Data 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 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);
// 이제 사용자 객체에는 ID가 포함될 것입니다
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 키가 추출되어 필요하지 않은 데이터를 가져오는 것을 줄일 수 있습니다.
- 또한, 우리는 사용자와 맵 키 둘 다에 대해 쿼리를 수행했습니다. 어느 하나라도 찾을 수 없으면, 필요한 키가 발견되지 않았다는 뜻으로 빈 데이터를 반환합니다. 이렇게 하면 필요한 키가 없는 경우에는 사용자 객체를 가져오지 않아도 됩니다.
Spring Data 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"
}
}
GET 요청으로 API를 사용하여 모든 사용자를 가져올 수 있습니다:
https://localhost:8102/user/
다음과 같은 결과가 나올 것입니다:
[
{
"userId": "5a5f28cc3178058b0fafe1dd",
"name": "Shubham",
"creationDate": 1516165830856,
"userSettings": {
"bike" : "pulsar"
}
}
]
위의
UserController
클래스를 보면, 우리는 MongoTemplate을 사용하도록 연결하지 않았습니다. 아래 코드 스니펫은 사용자 설정을 읽기 위해 MongoTemplate을 사용하기 위해 필요한 변경 사항을 보여줍니다.
//정의 데이터 액세스 레이어 객체
private final UserDAL userDAL;
//생성자 자동연결을 통한 DAL 객체 초기화
public UserController(UserRepository userRepository, UserDAL userDAL) {
this.userRepository = userRepository;
this.userDAL = userDAL;
}
//DAL 및 따라서 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.";
}
}
//DAL 및 따라서 MongoTemplate 사용하도록 메서드 구현 변경
@RequestMapping(value = "/settings/{userId}/{key}", method = RequestMethod.GET)
public String getUserSetting(
@PathVariable String userId, @PathVariable String key) {
return userDAL.getUserSetting(userId, key);
}
앱을 다시 시작하고 모든 사용자 설정 및 특정 키를 가져오기 위해 시나리오 실행. 아래 이미지는 Postman 앱에서의 출력을 보여줍니다.
MongoTemplate 대 MongoRepository
- MongoTemplate은 데이터 쿼리 및 데이터베이스에서 데이터를 가져오는 데 더 많은 제어를 제공합니다.
- Spring Data 리포지토리는 데이터를 검색하는 방법에 대한 편리한 전망을 제공합니다.
- MongoTemplate은 데이터베이스 종속적입니다. 즉, Spring Data 리포지토리를 사용하면 MySQL이나 Neo4J 또는 기타 어떤 데이터베이스로든 간단히 전환할 수 있습니다. 이는 MongoTemplate로는 불가능합니다.
Spring Boot MongoDB 요약
이 수업에서는 MongoTemplate이 Spring Data 저장소에 대해 더 많은 제어를 제공할 수 있지만 더 깊은 쿼리가 포함된 경우 약간 복잡할 수 있다는 점을 살펴보았습니다. 따라서 여러분이 아이디어를 개발할 때 어떤 것을 선택할지는 완전히 여러분의 판단에 달려 있습니다. 아래에 댓글을 자유롭게 남겨 주세요. 아래 링크에서 소스 코드를 다운로드하세요. 제공된 앱을 실행하기 전에 MongoDB 자격 증명을 변경해야 합니다.
Source:
https://www.digitalocean.com/community/tutorials/spring-boot-mongodb