本文共 18208 字,大约阅读时间需要 60 分钟。
Welcome to Spring Boot example. Spring Boot is the easiest way to spin a spring project quickly and MongoDB is the most popular NoSQL database. Let’s see how to integrate spring with MongoDB database.
欢迎使用Spring Boot 示例。 Spring Boot是快速旋转Spring项目的最简单方法,而MongoDB是最受欢迎的NoSQL数据库。 让我们看看如何将spring与MongoDB数据库集成。
We need following APIs to work with Spring Boot and MongoDB database.
我们需要以下API来使用Spring Boot和MongoDB数据库。
There are two approaches through which we can connect to MongoDB database – 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 tool for quickly setting up the project. So, let’s get started.
我们可以通过两种方法连接到MongoDB数据库: MongoRepository
和MongoTemplate
。 我们将尝试确定一个API可以提供比另一个API更多的功能,以及何时应为您的用例选择它们中的任何一个。 我们将使用工具快速设置项目。 因此,让我们开始吧。
We will make use of Spring Initializr tool for quickly setting up the project. We will use just two dependencies as shown below:
我们将使用Spring Initializr工具快速设置项目。 我们将仅使用两个依赖项,如下所示:
Download the project and unzip it. Then import it into your favorite IDE – Eclipse or IntelliJ IDEA.
下载项目并解压缩。 然后将其导入您喜欢的IDE – Eclipse或IntelliJ IDEA。
Though we already completed the setup with the tool, if you want to set it up manually, we use Maven build system for this project and here are the dependencies we used:
尽管我们已经使用该工具完成了设置,但是如果您想手动设置它,我们将为该项目使用Maven构建系统,这是我们使用的依赖项:
4.0.0 com.journaldev.spring spring-boot-mongodb 0.0.1-SNAPSHOT jar spring-boot-mongodb Spring Boot MongoDB Example org.springframework.boot spring-boot-starter-parent 1.5.9.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-data-mongodb org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
Make sure to use stable version for from the maven central.
确保从Maven Central使用稳定版本的 。
We have a simple model class User.java
.
我们有一个简单的模型类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;@Documentpublic class User { @Id private String userId; private String name; private Date creationDate = new Date(); private MapuserSettings = 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 getUserSettings() { return userSettings; } public void setUserSettings(Map userSettings) { this.userSettings = userSettings; }}
We will have following functionalities and Database interactions in our app.
我们的应用程序中将具有以下功能和数据库交互。
Now we will use Spring Data MongoDB repository to access our data. Spring Data MongoRepository provide us common functionalities that we can easily plug-in and use it.
现在,我们将使用Spring Data MongoDB存储库访问我们的数据。 Spring Data MongoRepository为我们提供了常见的功能,我们可以轻松地插入和使用它。
Let us define our Repository interface.
让我们定义我们的Repository接口。
package com.journaldev.bootifulmongodb.dal;import org.springframework.data.mongodb.repository.MongoRepository;import org.springframework.stereotype.Repository;import com.journaldev.bootifulmongodb.model.User;@Repositorypublic interface UserRepository extends MongoRepository{}
Before we lay out our controller, it is important that we make a connection with a local instance of MongoDB. We will use Spring Boot properties to do this.
在布置控制器之前,重要的是要与MongoDB的本地实例建立连接。 我们将使用Spring Boot属性来执行此操作。
#Local MongoDB configspring.data.mongodb.authentication-database=adminspring.data.mongodb.username=rootspring.data.mongodb.password=rootspring.data.mongodb.database=user_dbspring.data.mongodb.port=27017spring.data.mongodb.host=localhost# App configserver.port=8102spring.application.name=BootMongoserver.context-path=/user
So, the app will run on port 8102 and connect to a local mongoDB instance with provided credentials. If you have a local instance without authorization enabled, you can just remove the first three lines of configuration.
因此,该应用程序将在端口8102上运行,并使用提供的凭据连接到本地mongoDB实例。 如果您有未启用授权的本地实例,则只需删除配置的前三行。
Let us finally move to making our Controller class.
最后,让我们开始制作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; }}
We just the repository interface dependency and we will use this next.
我们只是库接口的依赖,我们将使用这个未来。
For the functionalities we mentioned, we will now be making APIs and accessing the userRepository dependency which will internally use Spring Data MongoRepository API. Notice that we do not have to write any database interaction code in the interface as Spring Data does it all for us.
对于我们提到的功能,我们现在将制作API并访问将在内部使用Spring Data MongoRepository API的userRepository依赖项。 注意,我们不必在接口中编写任何数据库交互代码,因为Spring Data会为我们完成所有这些工作。
@RequestMapping(value = "", method = RequestMethod.GET)public ListgetAllUsers() { LOG.info("Getting all users."); return userRepository.findAll();}
findAll()
is just a method which Spring Data MongoRepository provides internally.
findAll()
只是Spring Data MongoRepository内部提供的一种方法。
Now, let us get a specific user with an 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.
findOne()
只是Spring Data MongoRepository内部提供的一种通过ID获取对象的方法。
We will be adding a new user in the function below.
我们将在下面的功能中添加一个新用户。
@RequestMapping(value = "/create", method = RequestMethod.POST)public User addNewUsers(@RequestBody User user) { LOG.info("Saving user."); return userRepository.save(user);}
Now that we have added sample data into the DB, let’s try to extract some part of it.
现在,我们已将示例数据添加到数据库中,让我们尝试提取其中的一部分。
@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."; }}
Notice in the above query, we got the user object, then extracted the complete Setting map (which could have contained 1000s of objects) and finally got our own value. This is a downside for Spring Data query when we use it as straight API.
注意,在上面的查询中,我们获得了用户对象,然后提取了完整的设置图(可能包含1000个对象),最后得到了我们自己的值。 当我们将Spring Data查询用作直接API时,这是不利的。
Let’s try to add some data to an existing user:
让我们尝试向现有用户添加一些数据:
@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."; }}
With all the code we wrote, it’s clear that we didn’t have to write a single line of code to access the database apart from defining the repository interface and autowiring the dependency.
使用我们编写的所有代码,很明显,除了定义存储库接口和自动装配依赖关系之外,我们无需编写任何代码即可访问数据库。
This is the ease Spring Data 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 Data MongoRepository
API可以轻松为我们提供服务,但也有一些缺点。 当我们还定义了MongoTemplate
版本时,我们将详细说明。 让我们也开始吧。
We will be defining the MongoTemplate database queries here. With MongoTemplate, you will see that we have much more granular control over what we query and what data is included in the results.
我们将在这里定义MongoTemplate数据库查询。 使用MongoTemplate,您将看到我们可以更精确地控制查询内容以及结果中包含的数据。
To provide a contract at the database access layer, we will start by defining an interface which works just like our Spring Data in-built methods.
为了在数据库访问层提供合同,我们将首先定义一个接口,该接口的工作方式与我们的Spring Data内置方法一样。
package com.journaldev.bootifulmongodb.dal;import java.util.List;import com.journaldev.bootifulmongodb.model.User;public interface UserDAL { ListgetAllUsers(); 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);}
Let’s move on and define these methods.
让我们继续并定义这些方法。
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;@Repositorypublic class UserDALImpl implements UserDAL { @Autowired private MongoTemplate mongoTemplate; @Override public ListgetAllUsers() { 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."; } }}
The method implementations in above class are using MongoTemplate dependency.
上一类中的方法实现使用MongoTemplate依赖项。
See how getUserById(...)
method gets the user. We construct a query and passed required parameters.
查看getUserById(...)
方法如何获取用户。 我们构造一个查询并传递必需的参数。
What will interests you more is the getUserSetting
query. Let us understand what happened above:
您更感兴趣的是getUserSetting
查询。 让我们了解上面发生的事情:
We can run this app simply by using a single command:
我们只需使用一个命令即可运行此应用程序:
mvn spring-boot:run
Once the app is running, we can try saving a new user by using this API:
应用程序运行后,我们可以尝试使用以下API保存新用户:
https://localhost:8102/user/create
As this will be a POST request, we will be sending JSON data as well:
由于这将是POST请求,因此我们还将发送JSON数据:
{ "name" : "Shubham", "userSettings" : { "bike" : "pulsar" }}
As we are returning the Mongo response itself, we will get something like:
当我们返回Mongo响应本身时,我们将得到类似以下内容:
{ "userId": "5a5f28cc3178058b0fafe1dd", "name": "Shubham", "creationDate": 1516165830856, "userSettings": { "bike" : "pulsar" }}
You can get all users by using the API as GET request:
您可以使用API作为GET请求来获取所有用户:
https://localhost:8102/user/
We will get back something like:
我们将得到类似的信息:
[ { "userId": "5a5f28cc3178058b0fafe1dd", "name": "Shubham", "creationDate": 1516165830856, "userSettings": { "bike" : "pulsar" } }]
If you see above 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.
如果您在UserController
类的上方看到,我们尚未连接要使用的MongoTemplate。 下面的代码片段显示了使用MongoTemplate读取用户设置所需的更改。
//define Data Access Layer objectprivate final UserDAL userDAL;//initialize DAL object via constructor autowiringpublic 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);}
Restart the app and run scenarios to get all user settings and to get any specific key. Below image shows the output from Postman app.
重新启动应用程序并运行方案以获取所有用户设置并获取任何特定密钥。 下图显示了Postman应用程序的输出。
In this lesson, we looked at how MongoTemplate can provide us more control over Spring Data repositories but can also be a little complicated when deeper queries are involved. So, this is completely your call what to choose when you develop your idea. Feel free to leave comments below.
在本课程中,我们研究了MongoTemplate如何为我们提供对Spring Data存储库的更多控制,但是当涉及到更深层次的查询时,它也会变得有些复杂。 因此,这完全是您提出想法时的选择。 随时在下面发表评论。
Download the source code from below link. Please make sure that you change the MongoDB credentials before running the provided app.
从下面的链接下载源代码。 在运行提供的应用程序之前,请确保您更改了MongoDB凭据。
翻译自:
转载地址:http://uymzd.baihongyu.com/