手把手教你在 Minecraft 插件中对接MongoDB数据库(Paper端)
在 Minecraft 服务器开发中,随着玩家数量和游戏机制的复杂度增加,传统的 YAML 或 JSON 文件存储往往力不从心。无论是玩家的经济数据、复杂的背包库存,还是跨服同步的需求,都需要一个高性能、灵活的数据库支持。
MongoDB 作为最流行的 NoSQL 数据库,其文档型结构(BSON)与 Java 对象天然契合,非常适合处理 Minecraft 中多变的数据结构。
本文将带你通过 Docker 快速搭建本地数据库环境,并演示如何在 PaperMC 插件中通过 Java 驱动无缝接入 MongoDB。
一、 环境准备
工欲善其事,必先利其器。在开始编码前,请确保你的开发环境已就绪:
- Docker Desktop:用于本地容器化运行 MongoDB,免去繁琐的安装配置。
- JDK 21+:推荐使用较新的 Java 版本以获得更好的性能(Minecraft 1.20.6+ 需要 Java 21)。
- PaperMC 服务端:作为目前性能最优的 Minecraft 服务端核心之一。
- Maven/Gradle:用于依赖管理和构建。
二、 极速部署:通过 Docker 启动 MongoDB
相比于注册云服务(如 Atlas)或在本机安装庞大的数据库软件,使用 Docker 是最优雅的开发姿势。
打开终端,运行以下命令即可启动一个 MongoDB 实例:
docker run -d \ --name mc-mongo \ -p 27017:27017 \ mongo:latest
命令解析:
-d:后台静默运行。--name mc-mongo:给容器起个名字,方便管理。-p 27017:27017:将容器内的数据库端口映射到本机的 27017 端口。mongo:latest:使用官方最新的镜像。
启动后,你可以使用任何 MongoDB 可视化工具(如 Compass 或 Navicat)连接 mongodb://localhost:27017 进行验证。
三、 服务端搭建:PaperMC
- 下载 PaperMC 的核心 JAR 包。
- 在空文件夹中运行:
java -jar paper-x.x.x.jar。 - 首次运行会生成
eula.txt,将其中的false改为true。 - 再次运行服务端,等待启动完成,输入
stop关闭服务器。
四、 核心开发:插件接入数据库
我们将创建一个简单的插件,在服务器启动时自动连接到我们刚才用 Docker 启动的数据库。
1. 引入 Maven 依赖
在你的 pom.xml 中,我们需要引入 Spigot/Paper API 以及 MongoDB 的同步驱动。
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
2. 配置文件管理
为了避免硬编码,我们在 src/main/resources 下创建一个 config.properties(或者直接利用 Bukkit 自带的 config.yml,这里为了演示纯 Java 逻辑使用属性文件),写入本地连接串:
# 连接到本地 Docker 容器 mongo.uri=mongodb://localhost:27017 mongo.database=minecraft_data
3. 编写生命周期逻辑
在插件的主类中,我们需要在 onEnable 阶段初始化连接,在 onDisable 阶段释放资源。
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.InputStream;
import java.util.Properties;
public class MongoPlugin extends JavaPlugin {
private MongoClient mongoClient;
private MongoDatabase database;
@Override
public void onEnable() {
getLogger().info("正在初始化 MongoDB 连接...");
// 加载配置
Properties props = new Properties();
try (InputStream input = getResource("config.properties")) {
if (input == null) {
getLogger().severe("未找到配置文件,插件即将关闭!");
getServer().getPluginManager().disablePlugin(this);
return;
}
props.load(input);
} catch (Exception e) {
e.printStackTrace();
return;
}
// 建立连接
String uri = props.getProperty("mongo.uri");
String dbName = props.getProperty("mongo.database");
try {
// 创建客户端实例
mongoClient = MongoClients.create(uri);
database = mongoClient.getDatabase(dbName);
getLogger().info("成功连接到数据库: " + dbName);
// 测试:打印当前所有集合名称
database.listCollectionNames().forEach(name ->
getLogger().info("发现集合: " + name)
);
} catch (Exception e) {
getLogger().severe("数据库连接失败!请检查 Docker 是否运行。");
e.printStackTrace();
}
}
@Override
public void onDisable() {
// 优雅关闭连接,防止资源泄漏
if (mongoClient != null) {
mongoClient.close();
getLogger().info("MongoDB 连接已断开。");
}
}
// 提供给其他类调用的 Getter 方法
public MongoDatabase getDatabase() {
return database;
}
}
4. 注册插件 (plugin.yml)
别忘了在 src/main/resources 下创建 plugin.yml:
name: MongoDemo version: 1.0 main: com.yourpackage.MongoPlugin api-version: 1.20
五、 构建与验证
- 打包:在项目根目录执行
mvn clean package。 - 安装:将生成的
.jar文件复制到 Paper 服务端的plugins目录。 - 运行:启动服务端。
如果一切顺利,你将在控制台中看到类似以下的绿色日志:
[MongoDemo] 正在初始化 MongoDB 连接... [MongoDemo] 成功连接到数据库: minecraft_data
这意味着你的 Minecraft 服务器已经成功“握手”了本地的 Docker 数据库。
六、 总结与展望
通过 Docker + MongoDB 的组合,我们摆脱了对云服务的依赖,建立了一个低延迟、完全可控的开发环境。
在此基础上,你可以继续扩展功能:
- 玩家数据持久化:编写监听器(Listener),在玩家
PlayerJoinEvent时读取数据,在PlayerQuitEvent时保存数据。 - 排行榜系统:利用 MongoDB 强大的聚合查询(Aggregation)制作全服财富榜或击杀榜。
- 异步处理:为了不卡顿主线程(TPS),建议配合
BukkitRunnable进行异步数据库读写。
数据库的引入是 Minecraft 插件开发的重要一步。希望本文能为你打开新的思路。
Happy Coding!
