Поиск по сайту:

Весенняя загрузка MongoDB


Добро пожаловать в пример Spring Boot MongoDB. Spring Boot — это самый простой способ быстро запустить весенний проект, а MongoDB — самая популярная база данных NoSQL. Давайте посмотрим, как интегрировать Spring с базой данных MongoDB.

Весенняя загрузка MongoDB

Нам нужны следующие API для работы с базой данных Spring Boot и MongoDB.

  • Пружинные данные MongoDB
  • Весенняя загрузка

Есть два подхода, с помощью которых мы можем подключиться к базе данных MongoDB — MongoRepository и MongoTemplate. Мы постараемся установить, что предлагает один API по сравнению с другим, и когда вы должны выбрать любой из них для своего варианта использования. Мы будем использовать инструмент Spring Initializr для быстрой настройки проекта. Итак, приступим.

Настройка проекта Spring Boot MongoDB

Зависимости Maven

Хотя мы уже завершили настройку с помощью инструмента, если вы хотите настроить его вручную, мы используем систему сборки 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>

Обязательно используйте стабильную версию для Spring Boot из центра maven.

Класс модели 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;
	}
}

API-интерфейсы Spring Boot MongoDB

В нашем приложении будут следующие функции и взаимодействие с базой данных.

  • Получить всех пользователей
  • Получить пользователя с идентификатором
  • Получить пользовательские настройки
  • Получить определенный ключ с карты
  • Добавить/обновить пользовательские настройки

Spring Data MongoDB — MongoRepository

Теперь мы будем использовать репозиторий Spring Data MongoDB для доступа к нашим данным. Spring Data MongoRepository предоставляет нам общие функции, которые мы можем легко подключить и использовать. Давайте определим наш интерфейс репозитория.

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 с предоставленными учетными данными. Если у вас есть локальный экземпляр без включенной авторизации, вы можете просто удалить первые три строки конфигурации.

Определение контроллера Spring

Давайте, наконец, перейдем к созданию нашего класса 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;
	}
}

Мы только что автоматически подключили зависимость интерфейса репозитория, и мы будем использовать это дальше.

Определение 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

Теперь давайте получим конкретного пользователя с идентификатором.

@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 предоставляет внутри для получения объекта по идентификатору.

Добавление нового пользователя

Мы добавим нового пользователя в функцию ниже.

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

Получение настроек пользователя

Теперь, когда мы добавили образцы данных в БД, давайте попробуем извлечь из них какую-то часть.

@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 объектов) и, наконец, получили собственное значение. Это недостаток запроса Spring Data, когда мы используем его как прямой API.

Добавление новой настройки пользователя

Давайте попробуем добавить некоторые данные существующему пользователю:

@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 Данные 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 включает имена полей, которые должен включать результат при извлечении из БД. Это означает, что в этом случае ключ userSettings будет извлечен, что сэкономит много данных для выборки, которые не нужны
  • Кроме того, мы запросили как пользователя, так и ключ карты. Если какой-либо из них не найден, мы возвращаем пустые данные, означающие, что требуемый ключ не найден. Это позволяет вообще не получать объект User, если требуемый ключ отсутствует

Тестовый запуск 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"
  }
}
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 вы можете легко переключиться на другую базу данных, просто используя другой репозиторий Spring Data для MySQL, Neo4J или чего-то еще. Это невозможно с MongoTemplate.

Сводка по Spring Boot MongoDB

В этом уроке мы рассмотрели, как MongoTemplate может предоставить нам больший контроль над репозиториями данных Spring, но также может быть немного сложным, когда задействованы более глубокие запросы. Итак, это полностью ваш выбор, что выбрать, когда вы развиваете свою идею. Не стесняйтесь оставлять комментарии ниже. Загрузите исходный код по ссылке ниже. Убедитесь, что вы изменили учетные данные MongoDB перед запуском предоставленного приложения.

Скачать пример проекта Spring Boot MongoDB