欢迎使用Spring Boot蒙古达例子。Spring Boot是快速启动Spring项目的最简单方法,MongoDB是最流行的NoSQL数据库。让我们看看如何将spring与MongoDB数据库集成。
目录
Spring BootMongoDB
我们需要以下api来处理Spring Boot和MongoDB数据库。
- Spring数据MongoDB
- Spring Boot
有两种方法可以连接到MongoDB数据库–;MongoRepository
and MongoTemplate
. We will try to establish what one API offers over another and when should you choose any one of them for your use-case. We will make use of Spring初始化器快速设置项目的工具。那么,我们开始吧。
Spring Boot MongoDB项目设置
我们将使用springinitializer工具来快速设置项目。我们将只使用两个依赖项,如下所示:
下载项目并解压缩。然后将其导入到您最喜欢的IDE&;Eclipse或IntelliJ IDEA中。
Maven依赖项
虽然我们已经使用该工具完成了设置,但如果您想手动设置,我们将使用Maven build system来执行此项目,下面是我们使用的依赖项:
<?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从马文中心。
Spring启动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;
}
}
Spring启动MongoDB API
我们将在我们的应用程序中提供以下功能和数据库交互。
- 获取所有用户
- 获取ID为的用户
- 获取用户设置
- 从地图上取一把钥匙
- 添加/更新用户设置
Spring Data MongoDB和MongoRespository
现在我们将使用Spring Datamongodb存储库来访问我们的数据。Spring Datamongorepository为我们提供了一些常见的功能,我们可以很容易地将其插入并使用。
让我们定义我们的存储库。
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控制器
让我们最后来制作控制器类。
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 Datamongorepository API。请注意,我们不必在接口中编写任何数据库交互代码,因为Spring数据为我们完成了所有工作。
获取所有用户
@RequestMapping(value = "", method = RequestMethod.GET)
public List<User> getAllUsers() {
LOG.info("Getting all users.");
return userRepository.findAll();
}
findAll()
is just a method which Spring Data MongoRepository provides internally.
按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()
is just a method which Spring Data MongoRepository provides internally to get an Object by an ID.
添加新用户
我们将在下面的函数中添加一个新用户。
@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数据查询用作直接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.";
}
}
在我们编写的所有代码中,很明显,除了定义存储库接口和自动连接依赖项之外,我们不必编写一行代码来访问数据库。
这是易泉数据MongoRepository
API offers us but it also has some downsides. We will elaborate this when we have defined the MongoTemplate
version as well. Let’s get started with that too.
Spring数据MongoDB和MongoTemplate
我们将在这里定义MongoTemplate数据库查询。使用MongoTemplate,您将看到我们对查询的内容和结果中包含的数据有了更精细的控制。
定义DAL接口
为了在数据库访问层提供一个契约,我们将首先定义一个接口,它的工作方式与我们的Spring数据在构建方法中的工作方式一样。
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(...)
method gets the user. We construct a query and passed required parameters.
你更感兴趣的是getUserSetting
query. Let us understand what happened above:
- 我们用检查相等性的条件构造查询。
- include方法包含从数据库中提取结果时应包含的字段名。这意味着,在这种情况下,将提取userSettings密钥,这将保存大量不需要获取的数据
- 此外,我们还查询了user和map key。Id任何一个都找不到,返回空数据意味着找不到所需的密钥。如果不存在所需的密钥,甚至不必获取用户对象
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"
}
}
您可以使用API作为get请求获取所有用户:
https://localhost:8102/user/
我们会得到一些东西,比如:
[
{
"userId": "5a5f28cc3178058b0fafe1dd",
"name": "Shubham",
"creationDate": 1516165830856,
"userSettings": {
"bike" : "pulsar"
}
}
]
如果你看到上面UserController
class, we haven’t hooked up MongoTemplate to be used. Below code snippet shows the changes required to use MongoTemplate for reading user settings.
//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);
}
重新启动应用程序并运行方案以获取所有用户设置和任何特定密钥。下面显示了Postman的图像输出。
MongoTemplate与MongoRepository
- MongoTemplate在查询数据和从数据库中提取哪些数据时提供了更多的控制。
- Spring数据仓库为我们提供了一个关于如何获取数据的方便的前景。
- MongoTemplate依赖于数据库。这意味着,使用Spring数据存储库,您只需为MySQL或Neo4J或其他任何东西使用不同的Spring数据存储库,就可以轻松地切换到不同的数据库。对于MongoTemplate,这是不可能的。
Spring启动MongoDB摘要
在这节课中,我们学习了MongoTemplate如何为我们提供对Spring数据仓库的更多控制,但是当涉及到更深层次的查询时,它也会变得有点复杂。所以,这完全取决于你在发展你的想法时要选择什么。欢迎在下面留言。
从下面的链接下载源代码。请确保在运行提供的应用程序之前更改MongoDB凭据。