对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

将MongoDB与 Quarkus 集成

在本指南中,您可以学习;了解如何创建Java REST API ,该 API 使用 Quarkus 作为 Web框架和 Eclipse JNoSQL 来访问权限MongoDB。Quarkus 是一个开源Java框架,专为云原生微服务和无服务器开发而设计。Eclipse JNOSQL 实现 Jakarta NoSQLJakarta Data 规范,以简化Java应用程序与 NoSQL 数据库的集成。

本教程中的应用程序由以下各层组成:

  • 数据库层:MongoDB提供数据存储和检索。

  • 应用程序层:Quarkus 处理HTTP请求、路由和依赖项注入。

  • 数据访问权限层:JNoSQL 提供MongoDB文档映射和存储库模式。

本教程使用 Quarkus JNoSQL 扩展访问权限MongoDB,该扩展为 NoSQL 数据库提供了统一的API ,并允许您通过熟悉的Java模式和注解来使用MongoDB 。因此,您可以使用MongoDB和 Quarkus 以最少的配置开发轻量级应用程序。

通过将MongoDB与 Quarkus 集成,您可以利用 Quarkus 的快速初创企业时间和高效的资源利用以及 MongoDB 灵活的文档模型。这种组合支持需要类型安全、可扩展性和快速开发周期的应用程序。您可以使用MongoDB和 Quarkus 来创建实际应用程序,例如微服务、云原生 API 或需要高性能和低资源消耗的系统。

本教程向您展示如何构建使用MongoDB和 Quarkus 的REST API 。该应用程序访问示例餐厅数据,查询数据,并通过 RESTful 终结点返回结果。本教程还包括连接到MongoDB Atlas上托管的MongoDB 集群的说明。

提示

如果您希望使用 Java 驱动程序而不使用 Quarkus 连接到 MongoDB,请参阅Java 驱动程序入门教程

按照本节中的步骤安装项目依赖项,创建Atlas集群,并设立应用程序结构。

1

要创建快速入门应用程序,请在开发环境中安装以下软件:

先决条件
注意

安装 JDK 版本 21 或更高版本。

使用 3.8.1 或更高版本。

此命令行界面允许您从终端创建和托管 Quarkus 项目。
重要提示:本教程使用版本 3.30.6,较新版本可能会导致错误。按照您的操作系统,遵循相应的安装说明安装特定版本。

代码编辑器

使用您选择的代码编辑器。

终端应用和shell

对于 MacOS 用户,请使用终端或类似应用。对于Windows用户,请使用 PowerShell 或命令提示符。

2

MongoDB Atlas是一项完全托管云数据库服务,用于托管MongoDB部署。如果您没有MongoDB 部署,可以通过完成MongoDB入门教程来免费创建MongoDB 集群。MongoDB入门教程还演示了如何将示例数据集加载到集群中,包括本教程中使用的 sample_restaurants数据库。

要连接到MongoDB 集群,必须使用连接字符串。要学习;了解如何检索连接字符串,请参阅MongoDB入门教程的添加连接字符串部分。

重要

将连接string保存在安全位置。

3

从终端运行以下命令,创建一个名为 quarkus-quickstart 的新 Quarkus项目,为 REST 终结点配置 Quarkus JNoSQL Extension for MongoDB和JSON序列化:

quarkus create app quarkus-quickstart --extensions=jnosql-mongodb,resteasy-jackson

然后,通过运行以下命令导航到项目目录:

cd quarkus-quickstart
4

导航到 src/main/resources/application.properties文件并添加以下配置属性:

jnosql.document.database=sample_restaurants
quarkus.mongodb.connection-string=<connection string>

此代码将配置与MongoDB 集群中 sample_restaurants数据库的连接。将 <connection string> 占位符替换为在上一步中保存的连接字符串。

5

Quarkus项目模板包含一些示例文件,您可以在本教程中删除这些文件。要删除这些不需要的文件,请选择与操作系统对应的标签页,然后从 quarkus-quickstart目录运行以下命令:

rm src/main/java/org/acme/Car.java
rm src/main/java/org/acme/Garage.java
rm src/test/java/org/acme/GarageTest.java
rm src/main/java/org/acme/GreetingResource.java
rm src/test/java/org/acme/GreetingResourceIT.java
rm src/test/java/org/acme/GreetingResourceTest.java
del src/main/java/org/acme/Car.java
del src/main/java/org/acme/Garage.java
del src/test/java/org/acme/GarageTest.java
del src/main/java/org/acme/GreetingResource.java
del src/test/java/org/acme/GreetingResourceIT.java
del src/test/java/org/acme/GreetingResourceTest.java

设置项目结构和依赖项后,请按照本节中的步骤创建数据模型、存储库类和 REST 终结点。

1

src/main/java/org/acme目录中创建名为 Restaurant.java 的文件,然后粘贴以下代码:

quarkus-quickstart/src/main/java/org/acme/Restaurant.java
package org.acme;
import jakarta.nosql.Column;
import jakarta.nosql.Entity;
import jakarta.nosql.Id;
/**
* Represents a restaurant entity from the sample_restaurants database .
* This class is used as an entity in the MongoDB database.
*/
@Entity("restaurants")
public class Restaurant {
@Id
private String id;
@Column
private String name;
@Column
private String borough;
@Column
private String cuisine;
// Default constructor required by JNoSQL
public Restaurant() {}
// Constructor
public Restaurant(String id, String name, String borough,String cuisine) {
this.id = id;
this.name = name;
this.borough = borough;
this.cuisine = cuisine;
}
// Getters and setters
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBorough() { return borough; }
public void setBorough(String borough) { this.borough = borough; }
public String getCuisine() { return cuisine; }
public void setCuisine(String cuisine) { this.cuisine = cuisine; }
}

此文件定义了 Restaurant 实体类,它映射到 sample_restaurants.restaurants集合中的文档。@Entity 注释将此类标记为 JNoSQL 实体,字段注释将Java属性映射到文档字段。

2

src/main/java/org/acme目录中创建名为 RestaurantRepository.java 的文件,然后粘贴以下代码:

quarkus-quickstart/src/main/java/org/acme/RestaurantRepository.java
package org.acme;
import jakarta.data.repository.Repository;
import org.eclipse.jnosql.mapping.NoSQLRepository;
import java.util.List;
/**
* Interface for managing restaurant data.
*
* It uses the Jakarta Data Specification capabilities.
*
*/
@Repository
public interface RestaurantRepository extends NoSQLRepository<Restaurant, String> {
List<Restaurant> findByBorough(String borough);
List<Restaurant> findByCuisine(String cuisine);
}

该存储库库类提供了访问MongoDB中餐厅数据的方法。它定义了自定义 findByBorough()findByCuisine()查询方法,您还可以使用 RestaurantRepository实例访问权限内置的创建、读取、更新和删除方法。

3

src/main/java/org/acme目录中,创建名为 RestaurantResource.java 的文件并粘贴以下代码:

quarkus-quickstart/src/main/java/org/acme/RestaurantResource.java
package org.acme;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
/**
* REST API controller for restaurant operations.
* Provides endpoints for retrieving restaurant data from MongoDB.
*/
@Path("/restaurants")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class RestaurantResource {
@Inject
RestaurantRepository restaurantRepository;
/**
* Retrieves all restaurants from the database.
*
* @return List of all restaurants
*/
@GET
public Response getAllRestaurants() {
try {
List<Restaurant> restaurants = restaurantRepository.findAll().toList();
System.out.println("Found " + restaurants.size() + " restaurants");
return Response.ok(restaurants).build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error retrieving restaurants: " + e.getMessage())
.build();
}
}
/**
* Retrieves filtered restaurants in Queens that contain "Moon" in the name.
*
* @return List of filtered restaurants
*/
@GET
@Path("/browse")
public Response getFilteredRestaurants() {
try {
// Temporarily use findAll() to test basic connectivity
List<Restaurant> allRestaurants = restaurantRepository.findAll().toList();
System.out.println("Total restaurants found: " + allRestaurants.size());
// Filter for Queens restaurants that also have "Moon" in the name
List<Restaurant> queensRestaurants = allRestaurants.stream()
.filter(restaurant -> "Queens".equals(restaurant.getBorough()) &&
restaurant.getName() != null &&
restaurant.getName().toLowerCase().contains("moon"))
.toList();
System.out.println("Queens restaurants found: " + queensRestaurants.size());
return Response.ok(queensRestaurants).build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error retrieving filtered restaurants: " + e.getMessage())
.build();
}
}
/**
* Retrieves restaurants by cuisine type.
*
* @param cuisine The cuisine type to filter for
* @return List of restaurants that have the specified cuisine
*/
@GET
@Path("/cuisine/{cuisine}")
public Response getRestaurantsByCuisine(@PathParam("cuisine") String cuisine) {
try {
List<Restaurant> restaurants = restaurantRepository.findByCuisine(cuisine);
return Response.ok(restaurants).build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error retrieving restaurants by cuisine: " + e.getMessage())
.build();
}
}
}

此 REST资源类定义以下HTTP终结点:

  • GET /restaurants/:检索 restaurants集合中的所有文档

  • GET /restaurants/browse:检索代表皇后区名称中包含 "Moon" 的餐厅的文档,执行不区分大小写的查询

  • GET /restaurants/cuisine/{cuisine}:检索代表提供指定 cuisine 值的餐厅的文档

4

src/test/java/org/acme目录中,创建名为 RestaurantRepositoryTest.java 的文件并粘贴以下代码:

quarkus-quickstart/src/test/java/org/acme/RestaurantRepositoryTest.java
package org.acme;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* RestaurantRepositoryTest is a test class for testing the RestaurantRepository operations.
*
* It uses the Quarkus Test framework to test the restaurant data access.
*/
@QuarkusTest
public class RestaurantRepositoryTest {
@Inject
RestaurantRepository restaurantRepository;
@Test
@DisplayName("Should retrieve restaurants from the database")
public void testRetrieveRestaurants() {
// Test repository injection and MongoDB connection
assertThat(restaurantRepository).isNotNull();
}
@Test
@DisplayName("Should find restaurants by borough")
public void testFindRestaurantsByBorough() {
// Test that the method exists and returns data
List<Restaurant> restaurants = restaurantRepository.findByBorough("Queens");
assertThat(restaurants).isNotNull();
}
}

该文件使用 Quarkus 的测试框架进行集成测试。该代码定义了以下方法来测试MongoDB连接:

  • testRetrieveRestaurants():验证您的 RestaurantRepository 类是否可以访问MongoDB

  • testFindRestaurantsByBorough():验证 findByBorough() 方法是否检索MongoDB数据

最后,按照本部分中的步骤运行REST API并使用 curl 命令测试终结点。

1

首先,从项目目录运行以下命令来运行测试套件:

./mvnw test

此命令运行 RestaurantRepositoryTest 类并验证您的应用程序是否可以访问权限MongoDB数据。如果成功,命令输出将包含以下信息:

[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: ... s
[INFO] Finished at: ...
[INFO] ------------------------------------------------------------------------
2

在项目目录中,运行以下命令以编译并在开发模式下启动应用程序:

./mvnw quarkus:dev
3

在单独的终端窗口中,运行以下 curl 命令以测试 REST 终结点。每个终结点返回包含 sample_restaurants.restaurants集合中的餐厅信息的JSON数据。如果成功,您的命令将返回与示例输出类似的数据。

  1. 检索所有餐厅。

    curl http://localhost:8080/restaurants/
    [{"id":"...","name":"Morris Park Bake Shop","borough":"Bronx","cuisine":"Bakery"},
    {"id":"...","name":"Wilken'S Fine Food","borough":"Brooklyn","cuisine":"Delicatessen"},
    {"id":"...","name":"Taste The Tropics Ice Cream","borough":"Brooklyn","cuisine":"Ice Cream,
    Gelato, Yogurt, Ices"},
    {"id":"...","name":"Carvel Ice Cream","borough":"Queens","cuisine":"Ice Cream, Gelato, Yogurt,
    Ices"},
    ...]
  2. 检索名称中包含 "Moon" 的皇后区餐厅。

    curl http://localhost:8080/restaurants/browse
    [{"id":"...","name":"Somoon","borough":"Queens","cuisine":"Asian"},
    {"id":"...","name":"New Moon Star Restaurant","borough":"Queens","cuisine":"Chinese"},
    {"id":"...","name":"Moon Tikka Grill","borough":"Queens","cuisine":"Indian"},
    {"id":"...","name":"Silver Moon Diner","borough":"Queens","cuisine":"American"},
    {"id":"...","name":"Mooney'S Public House","borough":"Queens","cuisine":"Irish"},
    {"id":"...","name":"Moon Light Crill Rest.","borough":"Queens","cuisine":"Indian"},
    {"id":"...","name":"Full Moon Cafe","borough":"Queens","cuisine":"Café/Coffee/Tea"},
    {"id":"...","name":"Pacific Moon","borough":"Queens","cuisine":"Chinese"},
    {"id":"...","name":"Moon Palace Kitchen","borough":"Queens","cuisine":"Chinese"},
    {"id":"...","name":"Honey Moon Coffee Shop 1766096115682","borough":"Queens","cuisine":"Café/Coffee/Tea"},
    {"id":"...","name":"Honey Moon Coffee Shop","borough":"Queens","cuisine":"Café/Coffee/Tea"}]
  3. 按菜系类型检索餐厅。

    以下命令会查询 cuisine 值为 "Czech" 的餐厅,但您可以将此参数替换为任何菜系:

    curl http://localhost:8080/restaurants/cuisine/Czech
    [{"id":"...","name":"Koliba Restaurant","borough":"Queens","cuisine":"Czech"},
    {"id":"...","name":"Milan'S Restaurant","borough":"Brooklyn","cuisine":"Czech"},
    {"id":"...","name":"Bohemian Beer Garden","borough":"Queens","cuisine":"Czech"},
    {"id":"...","name":"Hospoda","borough":"Manhattan","cuisine":"Czech"},
    {"id":"...","name":"Olde Prague Tavern","borough":"Queens","cuisine":"Czech"},
    {"id":"...","name":"Brooklyn Beet Company","borough":"Brooklyn","cuisine":"Czech"}]

恭喜您完成 Quarkus 快速入门教程!完成这些步骤后,您就拥有一个Java Quarkus REST API ,它可以连接到MongoDB 部署、对示例餐厅数据运行查询,并通过HTTP终结点公开结果,您可以使用 curl 命令测试这些终结点。

要学习有关 Quarkus、JNoSQL 和 MongoDB 的更多信息,请参阅以下资源: