SpringBoot 2 使用 MongoDB 访问数据

开篇词

该指南将引导你使用 Spring Data MongoDB 构建应用,该应用将数据存储在 MongoDB (基于文档的好数据库)中,并从其中中检索数据。
 

你将创建的应用

我们将使用 Spring Data MongoDB 将 Customer POJO(普通的 Jvaa 对象)存储在 MongoDB 数据库中。
 

你将需要的工具

如何完成这个指南

像大多数的 Spring 入门指南一样,你可以从头开始并完成每个步骤,也可以绕过你已经熟悉的基本设置步骤。如论哪种方式,你最终都有可以工作的代码。

  • 要从头开始,移步至从 Spring Initializr 开始
  • 要跳过基础,执行以下操作:
    • 下载并解压缩该指南将用到的源代码,或借助 Git 来对其进行克隆操作:git clone https://github.com/spring-guides/gs-accessing-data-mongodb.git
    • 切换至 gs-accessing-data-mongodb/initial 目录;
    • 跳转至该指南的安装并启动 MongoDB

待一切就绪后,可以检查一下 gs-accessing-data-mongodb/complete 目录中的代码。
 

从 Spring Initializr 开始

对于所有的 Spring 应用来说,你应该从 Spring Initializr 开始。Initializr 提供了一种快速的方法来提取应用程序所需的依赖,并为你完成许多设置。该示例仅需要 Spring Data MongoDB 依赖。下图显示了此示例项目的 Initializr 设置:
Spring Initializr 界面

上图显示了选择 Maven 作为构建工具的 Initializr。你也可以使用 Gradle。它还将 com.exampleaccessing-data-mongodb 的值分别显示为 Group 和 Artifact。在本示例的其余部分,将用到这些值。

以下清单显示了选择 Maven 时创建的 pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>accessing-data-mongodb</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>accessing-data-mongodb</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<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-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

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

</project>

以下清单显示了在选择 Gradle 时创建的 build.gradle 文件:

plugins {
	id 'org.springframework.boot' version '2.2.0.RELEASE'
	id 'io.spring.dependency-management' version '1.0.8.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

test {
	useJUnitPlatform()
}

安装并启动 MongoDB

完成项目搭建后,我们可以安装和启动 MongoDB 数据库。

如果用的是 Mac 上的 Homebrew,则可以运行以下命令:

brew install mongodb

由官网提供的以上这条命令的执行结果与我本地的不一样,我需要这样才能运行:brew install mongodb-community。并且我还需要创建 /data/db 目录:mkdir -p /data/db。以及为其设置权限:sudo chown -R $USER /data/db

如果是 MacPorts 的话,可以运行以下命令:

port install mongodb

对于其他具有包管理的系统,例如 RedHat、Ubuntu、Debian、CentOS 以及 Windows,请参考 https://docs.mongodb.org/manual/installation/ 上的说明。
安装 MongoDB 之后,我们可以通过运行以下命令在控制台窗口中启动它(这也会启动服务器进程):

mongod

我们应该看到类似于以下输出的内容:

all output going to: /usr/local/var/log/mongodb/mongo.log

定义简单实体

MongoDB 是 NoSQL 文档存储。在该示例中,我们存储 Customer 对象。以下清单显示了 Customer 类(在 src/main/java/com/example/accessingdatamongodb/Customer.java 中):

package com.example.accessingdatamongodb;

import org.springframework.data.annotation.Id;


public class Customer {

  @Id
  public String id;

  public String firstName;
  public String lastName;

  public Customer() {}

  public Customer(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @Override
  public String toString() {
    return String.format(
        "Customer[id=%s, firstName='%s', lastName='%s']",
        id, firstName, lastName);
  }

}

这里,我们有一个 Customer 类,其具有三个属性:idfirstNamelastName。该 id 主要供 MongoDB 内部使用。创建新实例时,我们还可以使用一个构造函数来填充实体。

在该指南中,为简洁起见,省略了典型的 getter 和 setter。

id 于 Mongo ID 的标准名称相匹配,因此它不需要任何特殊注解就可供 Spring Data MongoDB 来使用了。

其他两个属性,firstNamelastName,未被标注。假定将它们映射到与属性名称相同的字段。

方便的 toString() 方法可打印出有关客户的详细信息。

MongoDB 将数据存储在集合中。Spring Data MongoDB 将 Customer 类映射到一个名为 customer 的集合中。如果要更改集合的名称,可以在类上使用 Spring Data MongoDB 的 @Document 注解。

创建简单查询

Spring Data MongoDB 专注于在 MongoDB 中存储数据。它还从 Spring Data Commons 项目继承了功能,例如导出查询功能。本质上,我们无需学习 MongoDB 的查询语言。我们可以编写一些为我们提供好的方法。

要查看其效果,请创建一个查询 Customer 文档的存储库接口,如以下清淡(在 src/main/java/com/example/accessingdatamongodb/CustomerRepository.java 中)所示:

package com.example.accessingdatamongodb;

import java.util.List;

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

public interface CustomerRepository extends MongoRepository<Customer, String> {

  public Customer findByFirstName(String firstName);
  public List<Customer> findByLastName(String lastName);

}

CustomerRepository 扩展了 MongoRepository 接口,并插入了其可使用的值和 ID 的类型:分别为 CustomerString。该接口包含许多操作,包括标准的 CRUD(创建、读取、更新和删除)。

我们可以通过声明其他查询的方法签名来定义它们。在这种情况下,添加 findByFirstName,这实际上会查找类行为 Customer 的文档并查找与 firstName 匹配的文档。

我们还可以使用 findByLastName 来查找姓氏列表。

在典型的 Java 应用中,我们编写一个实现 CustomerRepository 的类,并自己编写查询。Spring Data MongoDB 之所以如此有用,是因为我们无需创建该实现。当我们运行应用时,Spring Data MongoDB 会即时创建它。

现在,我们可以连接该应用,并查看其结果!
 

创建应用类

Spring Initializr 为应用创建一个简单类。以下清单显示了 Initializr 为该示例创建的类(在 src/main/java/com/example/accessingdatamongodb/AccessingDataMongodbApplication.java 中):

package com.example.accessingdatamongodb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AccessingDataMongodbApplication {

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataMongodbApplication.class, args);
  }

}

@SpringBootApplication 是一个便利的注解,它添加了以下所有内容:

  • @Configuration:将类标记为应用上下文 Bean 定义的源;
  • @EnableAutoConfiguration:告诉 Spring Boot 根据类路径配置、其他 bean 以及各种属性的配置来添加 bean。
  • @ComponentScan:告知 Spring 在 com/example 包中寻找他组件、配置以及服务。

main() 方法使用 Spring Boot 的 SpringApplication.run() 方法启动应用。

只要它们被包含在 @SpringBootApplication 类的同一包(或子包)中,Spring Boot 就会自动处理这些存储库。为了更好地控制注册过程,可以使用 @EnableMongoRepositories 注解。

默认情况下,@EnableMongoReposiroeis 会在当前应用包中扫描任何扩展了 Spring Data 存储库接口之一的接口。如果我们的项目布局中有多个项目并且找不到存储库,则可以使用它的 basePackageClasses=MyRepository.class 安全地告诉 Spring Data MongoDB 按类型扫描另一个根包。

Spring Data MongoDB 使用 MongoTemplatefind* 方法后面执行查询。我们可以自己使用模版进行更复杂的查询,但是该指南并不涵盖该模版。(请参阅《Spring Data MongoDB 参考指南》)

现在,我们需要修改 Initializr 为我们创建的简单类。我们需要设置一些数据并将其用于生成输出。以下清单显示了完成的 AccessingDataMongodbApplication 类(在 src/main/java/com/example/accessingdatamongodb/AccessingDataMongodbApplication.java 中):

package com.example.accessingdatamongodb;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AccessingDataMongodbApplication implements CommandLineRunner {

  @Autowired
  private CustomerRepository repository;

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataMongodbApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {

    repository.deleteAll();

    // save a couple of customers
    repository.save(new Customer("Alice", "Smith"));
    repository.save(new Customer("Bob", "Smith"));

    // fetch all customers
    System.out.println("Customers found with findAll():");
    System.out.println("-------------------------------");
    for (Customer customer : repository.findAll()) {
      System.out.println(customer);
    }
    System.out.println();

    // fetch an individual customer
    System.out.println("Customer found with findByFirstName('Alice'):");
    System.out.println("--------------------------------");
    System.out.println(repository.findByFirstName("Alice"));

    System.out.println("Customers found with findByLastName('Smith'):");
    System.out.println("--------------------------------");
    for (Customer customer : repository.findByLastName("Smith")) {
      System.out.println(customer);
    }

  }

}

AccessingDataMongodbApplication 包含 main() 方法,该方法自动装配 CustomerRepository 的实例。Spring Data MongoDB 动态创建代理并将其注入到那里。我们通过一些测试来使用 CustomerRepository。首先,它保存了少量 Customer 对象,演示了 save() 方法并设置了一些要使用的数据。接下来,它调用 findAll() 从数据库中获取所有 Customer 对象。然后,它调用 findByFirstName() 来获取单个客户的名字。最后,它调用 findByLastName() 来查找姓氏为 Smith 的所有客户。

默认情况下,Spring Boot 尝试连接到本地托管的 MongoDB 实例。阅读参考文档,以获取有关将我们的应用指向托管在其他地方的 MongoDB 实例的详细信息。

构建可执行 JAR

我们可以结合 Gradle 或 Maven 来从命令行运行该应用。我们还可以构建一个包含所有必须依赖项、类以及资源的可执行 JAR 文件,然后运行该文件。在整个开发生命周期中,跨环境等等情况下,构建可执行 JAR 可以轻松地将服务作为应用进行发布、版本化以及部署。

如果使用 Gradle,则可以借助 ./gradlew bootRun 来运行应用。或通过借助 ./gradlew build 来构建 JAR 文件,然后运行 JAR 文件,如下所示:

java -jar build/libs/gs-accessing-data-mongodb-0.1.0.jar

由官网提供的以上这条命令的执行结果与我本地的不一样,我需要这样才能运行:java -jar build/libs/accessing-data-mongodb-0.0.1-SNAPSHOT.jar

如果使用 Maven,则可以借助 ./mvnw spring-boot:run 来运行该用。或可以借助 ./mvnw clean package 来构建 JAR 文件,然后运行 JAR 文件,如下所示:

java -jar target/gs-accessing-data-mongodb-0.1.0.jar

由官网提供的以上这条命令的执行结果与我本地的不一样,我需要这样才能运行:java -jar target/accessing-data-mongodb-0.0.1-SNAPSHOT.jar

我们还可以构建一个经典的 WAR 文件

当 AccessingDataMongodbApplication 实现 CommandLineRunner 时,Spring Boot 启动时将自动调用 run 方法。我们应该看到类似以下输出的内容(以及其他输出,例如查询):

== Customers found with findAll():
Customer[id=51df1b0a3004cb49c50210f8, firstName='Alice', lastName='Smith']
Customer[id=51df1b0a3004cb49c50210f9, firstName='Bob', lastName='Smith']

== Customer found with findByFirstName('Alice'):
Customer[id=51df1b0a3004cb49c50210f8, firstName='Alice', lastName='Smith']
== Customers found with findByLastName('Smith'):
Customer[id=51df1b0a3004cb49c50210f8, firstName='Alice', lastName='Smith']
Customer[id=51df1b0a3004cb49c50210f9, firstName='Bob', lastName='Smith']

概述

恭喜你!我们设置了一个 MongoDB 服务器,并编写了一个简单的应用,该应用使用 Spring Data MongoDB 将对象保存到数据库并从数据库中获取对象,而无需编写具体的存储库实现。

如果我们想轻松地使用基于超媒体的 RESTful 前端公开 MongoDB 存储库,请阅读使用 REST 访问 MongoDB 数据(尽请期待~)。

参见

以下指南也可能会有所帮助:

想看指南的其他内容?请访问该指南的所属专栏:《Spring 官方指南

发布了139 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/stevenchen1989/article/details/104243808
今日推荐