1. 引言

Quarkus 是一款专为打造低内存占用、快速启动的 Java 应用而优化的热门框架。当它与流行的 NoSQL 数据库 MongoDB 结合时,Quarkus 提供了一套强大的工具集,用于开发高性能、可扩展的应用程序。

本教程将带你探索:

  • ✅ Quarkus 与 MongoDB 的配置
  • ✅ 基础 CRUD 操作实现
  • ✅ 使用 Panache(Quarkus 的 ODM)简化数据访问

2. 配置

2.1. Maven 依赖

要在 Quarkus 中使用 MongoDB,需添加以下核心依赖:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-mongodb-client</artifactId>
    <version>3.13.0</version>
</dependency>

此依赖提供了通过 MongoDB Java 客户端与数据库交互所需的所有工具。

2.2. 运行 MongoDB 数据库

本教程采用 Docker 容器运行 MongoDB,这是最便捷的部署方式(避免本地安装的麻烦):

docker pull mongo:latest
docker run --name mongodb -d -p 27017:27017 mongo:latest

⚠️ 确保本地已安装 Docker 且端口 27017 未被占用

2.3. 配置 MongoDB 连接

核心配置项是连接字符串,它几乎能涵盖所有连接参数:

quarkus.mongodb.connection-string = mongodb://localhost:27017

本示例使用单节点配置,生产环境可扩展为副本集配置

3. 基础 CRUD 操作

3.1. 定义实体类

创建 Article 实体类表示 MongoDB 文档:

public class Article {
    @BsonId
    public ObjectId id;
    public String author;
    public String title;
    public String description;
    
    // getters and setters 
}

关键点:

  • @BsonId 注解将字段映射为 MongoDB 的 _id 标识符
  • ObjectId 是 BSON(JSON 二进制格式)的默认 ID 类型
  • 每个文档必须包含唯一标识符用于高效索引和检索

3.2. 定义仓库类

创建 ArticleRepository 处理数据持久化:

@Inject
MongoClient mongoClient;

private MongoCollection<Article> getCollection() {
    return mongoClient.getDatabase("articles").getCollection("articles", Article.class);
}

public void create(Article article) {
    getCollection().insertOne(article);
}

public List<Article> listAll() {
    return getCollection().find().into(new ArrayList<>());
}

public void update(Article article) {
    getCollection().replaceOne(new org.bson.Document("_id", article.id), article);
}

public void delete(String id) {
    getCollection().deleteOne(new org.bson.Document("_id", new ObjectId(id)));
}

操作说明:

  • create():插入新文档
  • listAll():查询所有文档
  • update():替换整个文档(⚠️ 非字段级更新)
  • delete():根据 ID 删除文档

3.3. 定义资源类

创建 REST 接口层(为简化演示,省略了 Service 层):

@Path("/articles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ArticleResource {
    @Inject
    ArticleRepository articleRepository;

    @POST
    public Response create(Article article) {
        articleRepository.create(article);
        return Response.status(Response.Status.CREATED).build();
    }

    @GET
    public List<Article> listAll() {
        return articleRepository.listAll();
    }

    @PUT
    public Response update(Article updatedArticle) {
        articleRepository.update(updatedArticle);
        return Response.noContent().build();
    }

    @DELETE
    @Path("/{id}")
    public Response delete(@PathParam("id") String id) {
        articleRepository.delete(id);
        return Response.noContent().build();
    }
}

3.4. API 测试

使用 curl 命令测试接口:

创建文章:

curl -X POST http://localhost:8080/articles \
-H "Content-Type: application/json" \
-d '{"author":"John Doe","title":"Introduction to Quarkus","description":"A comprehensive guide to the Quarkus framework."}'

查询所有文章:

curl -X GET http://localhost:8080/articles

响应示例:

[
  {
    "id": "66a8c65e8bd3a01e0a509f0a",
    "author": "John Doe",
    "title": "Introduction to Quarkus",
    "description": "A comprehensive guide to Quarkus framework."
  }
]

4. 使用 Panache 简化开发

4.1. 添加 Panache 依赖

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-mongodb-panache</artifactId>
    <version>3.13.0</version>
</dependency>

4.2. 重构实体类

@MongoEntity(collection = "articles", database = "articles")
public class Article extends PanacheMongoEntityBase {
    private ObjectId id;
    private String author;
    private String title;
    private String description;

    // getters and setters
}

改进点:

  • 继承 PanacheMongoEntityBase 获得内置方法
  • @MongoEntity 明确指定集合和数据库
  • 无需手动编写 @BsonId 注解

4.3. 简化仓库类

@ApplicationScoped
public class ArticleRepository implements PanacheMongoRepository<Article> {}

✅ 空实现!Panache 已内置所有 CRUD 方法:

  • persist() - 创建
  • listAll() - 查询所有
  • findById() - 根据 ID 查询
  • delete() - 删除

4.4. 重构资源类

@Path("/v2/articles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ArticleResource {
    @Inject
    ArticleRepository articleRepository;

    @POST
    public Response create(Article article) {
        articleRepository.persist(article);
        return Response.status(Response.Status.CREATED).build();
    }

    @GET
    public List<Article> listAll() {
        return articleRepository.listAll();
    }

    @PUT
    public Response update(Article updatedArticle) {
        articleRepository.update(updatedArticle);
        return Response.noContent().build();
    }

    @DELETE
    @Path("/{id}")
    public Response delete(@PathParam("id") String id) {
        articleRepository.delete(id);
        return Response.noContent().build();
    }
}

❌ 注意:接口路径改为 /v2/articles 避免冲突

4.5. Panache 版 API 测试

使用相同 curl 命令测试新接口(仅修改路径):

创建文章:

curl -X POST http://localhost:8080/v2/articles \
-H "Content-Type: application/json" \
-d '{"author":"John Doe","title":"Introduction to MongoDB","description":"A comprehensive guide to MongoDB."}'

查询文章:

curl -X GET http://localhost:8080/v2/articles

5. 总结

本文完整演示了 Quarkus 与 MongoDB 的集成方案:

  1. 基础方案:直接使用 MongoDB Java 客户端

    • 优点:控制粒度细
    • 缺点:需编写大量模板代码
  2. 进阶方案:使用 Panache ODM

    • ✅ 大幅减少样板代码
    • ✅ 内置常用 CRUD 方法
    • ✅ 更符合 Java 开发习惯

代码示例已上传至 GitHub,建议结合实际项目需求选择方案。对于快速开发,强烈推荐 Panache 方案!


原始标题:Getting Started with MongoDB and Quarkus | Baeldung