MongoDB的安装配置及使用(WIndows/Java)

Posted HackShendi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB的安装配置及使用(WIndows/Java)相关的知识,希望对你有一定的参考价值。

Hi,I‘m Shendi


下面主要介绍使用 Windows安装 MongoDB 和使用 Java 操作

文章目录


MongoDB

MongoDB是一个基于分布式文件存储的数据库,由C++语言编写

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的,它支持的数据结构非常松散,是类型JSON的BSON格式,因此可以存储比较复杂的数据类型

特点是高性能、易部署、易使用,存储数据非常方便

NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"



下载

https://www.mongodb.com/try/download/community

我windows系统,选择的zip格式,解压缩后即可使用,如果是选择的msi,则直接双击运行安装即可

结构如下

可以先查阅README文件

其中 bin 目录下

  • mongod.exe(数据库服务器)
  • mongos.exe(分片)
  • Install-Compass.ps1(PowerShell脚本,执行后会安装Mongo的图形化工具)

执行Install-Compass.ps1后会安装MongoDBCompass,安装目录为 C:\\Users\\Administrator\\AppData\\Local

刚运行可能需要选择是否更改策略,输入 y 更改即可

将 bin 目录配置到环境变量,后面可直接使用 mongod 命令

Mongo 6.0后,bin目录下不再提供mongo.exe,如有需要可自行下载

https://www.mongodb.com/try/download/shell
我这里直接使用图形化工具 MongoDBCompass



创建数据目录

新建一个文件夹,一般命名为 data,用于存放数据库的数据



运行

使用 mongod --dbpath 来运行,其中dbpath为创建的数据目录

例如

mongod --dbpath C:/data

运行成功后结果大概如下,且命令行未结束

接下来就可以连接上 MongoDB 了(可以使用mongo.exe),使用图形化工具 MongoDBCompass,打开后直接点击Connect就连接成功了,默认端口27017



配置

可以创建一个配置文件,这样后期方便维护管理

在mongodb文件夹下新建一个文件,格式为 YAML

yaml 不支持 tab 键,只允许空格

所有配置可参考

https://mongodb.net.cn/manual/reference/configuration-options/

# 系统日志
systemLog:
 destination: file
 # 日志的目录
 path: "log/mongod.log"
 # 重启后,日志是否追加到现有日志末尾,false则新建一个日志文件,旧日志文件以日期后缀命名
 logAppend: true
# 存储配置
storage:
 # 数据目录地址
 dbPath: "data"
 # 指定存储引擎,但是我的加上此行就无法启动了
 # engine: WiredTiger
 # 指定内存 1代表1G,最小0.25
 wiredTiger:
  engineConfig:
   cacheSizeGB: 0.25
# 网络配置
net:
 # 绑定的ip,默认localhost,多个使用逗号分隔
 bindIp: localhost,127.0.0.1
 # 绑定的端口,默认27017
 port: 27017

使用以下命令指定配置文件运行

mongod --config 配置文件地址
# 或
mongod -f 配置文件地址
# 例如
mongod --config C:/config.yml


安装服务

–install 参数安装服务

例如

mongod --config 配置文件地址 --install

使用 --config 指定配置文件地址,需要注意的是,指定的配置文件路径及文件内的一些路径需为绝对路径,例如

mongod --config "C:/config.yml" --install
systemLog:
 destination: file
 path: "C:/Application/mongodb-win32-x86_64-windows-6.0.3/log/mongod.log"
 logAppend: true
storage:
 dbPath: "C:/Application/mongodb-win32-x86_64-windows-6.0.3/data"
net:
 bindIp: localhost,127.0.0.1
 port: 27017

命令

# 启动服务
net start MongoDB
# 关闭服务
net stop MongoDB
# 移除服务
mongod --remove

控制台需要为管理员权限,否则没有任何提示,在日志中可查看到

“msg”:“Error connecting to the Service Control Manager”,“attr”:“error”:“拒绝访问。 (5)”

服务和直接运行的方式使用一种即可

建议使用服务的方式运行,避免误操作关闭窗口导致MongoDB关闭



创建用户

MongoDB默认没有用户,且无需权限访问,如果在防火墙内不暴露出去则没有什么问题,否则需要进行以下配置

MongoDB 的用户是针对数据库而不是整个系统,所以所有数据库都需要设置

使用 MongoDB Compass 连接成功后,点击左下方 MONGOSH 即可输入命令

有命令提示,通过 use 数据库 即可更换数据库

# 进入admin数据库
use admin
# 创建超级管理员用户 - 拥有所有数据库的所有权限
db.createUser(
	user:"admin",
	pwd:"adminpwd",
	roles:[role:"root",db:"admin"],
	# 可选, 自定义信息
	customData: name : "Shendi"
)

其中 user 代表账号,pwd代表密码,roles中为此用户的角色,可指定多个

在配置文件添加

# 安全配置
security:
 # 是否启用权限验证 enabled启用, disabled禁用
 authorization: enabled

最后,重启 MongoDB/服务

net stop mongodb
net start mongodb

图形化界面

重新打开,或 disconnect

在新建连接时点击 Advanced Connection Options 选择 Authentication -> Username/Password

填写username,password,因为是 root 角色,可以不填database,然后 Connect 即可

命令行则使用

db.auth('账号','密码')

需要注意的是,同一个用户可以在多个地方同时登录,但有一个连接断开后,此用户的所有连接都失效

MongoDB Compass 和 Java 程序使用同一个用户,当 MongoDB Compass 断开连接后,导致 Java 报错


用户角色列表

  1. 数据库用户角色
    • read - 允许读取指定数据库的所有非系统集合,以及三个系统集合
      • system.indexes、system.js以及system.namesp
    • readWrite - 包含read的所有权限,以及修改所有非系统集合+system.js的数据
  2. 数据库管理角色
    • dbAdmin - 允许在指定数据库执行管理相关功能,例如查询统计信息,索引管理或访问 system.profile
    • dbOwner - 此角色为当前数据库的管理员,可以对数据库进行任何管理操作
    • userAdmin - 允许在指定数据库管理用户(增删改查),包括自己
  3. 集群管理角色 - 此类角色只能在 admin 数据库
    • clusterAdmin - 最高的集群访问权限,拥有其他集群管理角色的权限 + dropDatabase()权限
    • clusterManager - 对集群进行管理监控的权限
    • clusterMonitor - 对监控工具的只读访问权限
    • hostManager - 提供监控和管理服务器的权限
  4. 备份恢复角色
    • backup - 备份权限
    • restore - 还原权限
  5. 所有数据库角色 - 管理所有自定义数据库,不包含local和config数据库,此类角色只能在 admin 数据库
    • readAnyDatabase - 数据库读取的权限
    • readWriteAnyDatabase - 数据库读写的权限
    • userAdminAnyDatabase - 所有数据库的管理用户权限(userAdmin)
    • dbAdminAnyDatabase - 所有数据库的管理相关权限(dbAdmin)
  6. 超级用户角色
    • root - 所有权限
  7. 内部角色
    • __system - 仅用于 MongoDB 内部管理

其余用户操作

# 显示当前数据库所有用户
show users
# 更改密码
db.changeUserPassword("用户名","新密码")
# 修改用户 例 db.updateUser("admin", customData : name : "Shendi")
db.updateUser("用户名","要修改的数据":"值");
# 删除用户
db.dropUser("用户名")


Java使用

下载 MongoDB Java驱动
https://mongodb.github.io/mongo-java-driver/


Maven导入

<dependencies>
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongodb-driver-sync</artifactId>
        <version>4.7.2</version>
    </dependency>
</dependencies>

Gradle导入

dependencies 
  implementation 'org.mongodb:mongodb-driver-sync:4.7.2'

普通项目的话,除了要引入 mongodb-driver,还需要 bson 和 mongo-java-core 两个包

可以在maven仓库找到下载,或通过以下链接下载
https://download.csdn.net/download/qq_41806966/87079586


也可在文章最下方或在微信搜一搜sddxsck关注公众号后在公众号内发送 100000 获取

官方使用文档


数据库执行操作失败将抛出错误,所以一般需要使用 try catch 捕获



查询数据

下面是从官方复制的代码,大致意思是查找第一条指定数据库的指定collection下的包含指定key(title)+ 值(Back to the Future)的数据(Document)

import static com.mongodb.client.model.Filters.eq;
import org.bson.Document;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public static void main( String[] args ) 
    // Replace the uri string with your MongoDB deployment's connection string
    // String uri = "<connection string uri>";
    String uri = "mongodb://localhost:27017";
    try (MongoClient mongoClient = MongoClients.create(uri)) 
        MongoDatabase database = mongoClient.getDatabase("sample_mflix");
        MongoCollection<Document> collection = database.getCollection("movies");
        
        Document doc = collection.find(eq("title", "Back to the Future")).first();
        System.out.println(doc.toJson());
    

database为数据库,collection类似于表

如果有身份认证则 uri 与 MongoDB Compass 配置的 uri 一致即可

例如

// admin为用户名,adminpwd为密码, authSource为数据库,root角色可选
mongodb://admin:adminpwd@localhost:27017/?authMechanism=DEFAULT&authSource=admin

参数带有特殊字符则需要进行 url 编码

String account = URLEncoder.encode("admin", "UTF-8");
String pwd = URLEncoder.encode("adminpwd", "UTF-8");

StringBuilder tmp = new StringBuilder();
tmp.append("mongodb://").append(account).append(":").append(pwd)
    .append("@localhost:27017/?authMechanism=DEFAULT");

String uri = tmp.toString();

其中 /?authMechanism=DEFAULT 这一部分去掉,否则执行出错 Unsupported authMechanism: DEFAULT

获取的 Document 对象操作方法与 JSONObject 类似

例如获取列表,数据结构如下

代码及结果如下

其中 find() 查询所有数据可以使用游标 find().cursor() 或迭代器 find().iterator()

查询指定数量数据可以使用 find().limit(数量)

/** @author Shendi */
// cursor
MongoCursor<Document> cursor = collection.find().cursor();
while (cursor.hasNext()) 
    Document next = cursor.next();
    System.out.println(next.toJson());


// iterator
MongoCursor<Document> it = collection.find().iterator();
while (it.hasNext()) 
    Document next = it.next();
    System.out.println(next.toJson());



插入数据

插入数据使用 MongoCollection 的 insertOne(插入单个) 或 insertMany(插入多个)

每一个 Document 对应一条数据,插入数据则先创建 Document,Document实例与JSONObject/Map对象使用方法类似,也有 parse 函数用来将 json 转换

Document d = Document.parse("\\"name\\":\\"Shendi\\"");
// 插入数据
collection.insertOne(d);

d = new Document();
d.put("name", "Shendi");

collection.insertOne(d);

执行后可以看到新增了两条数据

也可以使用以下方法创建 Document

new Document().append("name", "Shendi").append("account", "admin");

insertMany函数则接收 List<Docuemnt>

List<Document> list = Arrays.asList(
	new Document().append("name", "Shendi"),
	new Document().append("name", "Shendi2"));
collection.insertMany(list);

insertOne 函数返回 InsertOneResult,insertMany 函数返回 InsertManyResult,可以用来获取刚插入数据的 id


例如

InsertOneResult one = collection.insertOne(d);
one.getInsertedId();

InsertManyResult many = collection.insertMany(list);
many.getInsertedIds();


修改数据

使用 MongoCollection 的 updateOne()、updateMany() 或 replaceOne()

Document 实现了 Bson

Updates生成器(一个包含静态助手方法的工厂类)用来构造Document,当然,也可以直接使用Document,例如 new Document(“$set”,new Document(“num”,1))

// Updates 中, set-直接设置,addToSet-将值添加到数组中 键必须为数组,currentTimestamp-字段值设置为当前时间戳
// 构建更新文档
Bson updates = Updates.combine(
	updates.set("num", 1),
	Updates.addToSet("love", new Document().append("name", "MongoDB").append("scope", 2)),
	Updates.currentTimestamp("updateTime"));

// 查找条件
Bson query = new Document().append("id", 1);

/*
    成功执行后,函数返回UpdateResult的实例,如果在UpdateOptions实例中指定了upstart(true),则可以通过调用getModifiedCount()方法检索修改的文档数,或者通过调用getUpsertedId()方法获取_id字段的值。
*/
UpdateOptions options = new UpdateOptions().upsert(true);
	    
UpdateResult result = collection.updateOne(query, updates, options);
System.out.println(result.getModifiedCount());

数据结构如下

运行后,结果如下

updateMany(修改多个)使用方法与updateOne(修改单个)一致

replaceOne (替换单个)函数从文档中删除所有现有字段和值(_id除外),并替换为替换文档

例如,将上面所示数据结构进行以下操作

/*
	与 UpdateOptions 相似,但可直接使用getModifiedCount(), 如果在ReplaceOptions实例中设置了upstart(true),并且该操作导致插入新文档,则还可以通过调用getUpsertedId() 方法来检索文档的_id字段的值
*/
ReplaceOptions options = new ReplaceOptions().upsert(true);
// 参数1为条件,参数2为值
UpdateResult result = collection.replaceOne(
    new Document().append("id", 1),
    new Document().append("id", "2").append("name", "Shendi"),
    options);
System.out.println(result.getModifiedCount());

最终结果变为



删除数据

使用 MongoCollection 的 deleteOne() 和 deleteMany()

判断条件使用 Filters 类,例如 Filters.eq(“id”, 2) 代表匹配 id=2 的数据,多个判断使用 Filters.and

这里将 id 为 2 的数据删除(上面替换时将 id 的值变为了字符串)

Bson query = Filters.eq("id", "2");
DeleteResult result = collection.deleteOne(query);
// 删除的数量
System.out.println(result.getDeletedCount());

deleteMany(删除所有匹配项) 使用方法同上



设置数据过期时间

给 Collection 设置字段 TTL(Time To Live) 索引,数据包含此字段的将会在指定时间后自动删除

在 MongoDB Compass 选择 Collection 后点击 Indexs,添加 TTL 索引

或通过命令行的方式

use Test
# test为collection名, expireAfterSeconds 为指定过期时间,单位秒
db.test.createIndex( "字段名": 1 ,  expireAfterSeconds: 3 )

添加数据时,对应此索引字段需要传递 Date,例如

2022-11-19T03:41:57.153+00:00

在Java中,直接传递 java.util.Date 即可,例如

coll.insertOne(new Document().append("time", new Date()));

不包含TTL索引的字段或字段值非Date则不会过期删除



其他问题

MongoClient是否需要关闭?

经过测试,MongoClient 实例可以作为全局变量,而无需关闭

即使MongoDB服务器关闭,重启后,MongoClient 也可以正常使用,只会报几次错

测试代码如下

package shendi.test.mongodb;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.bson.Document;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

/**
 * 测试
 * <br>
 * @author Shendi
 */
public class TestMongoDB 

	static MongoClient mongoClient;
	
	public static void main(String[] args) throws UnsupportedEncodingException, Exception 
		
		// Replace the uri string with your MongoDB deployment's connection string
		String account = URLEncoder.encode("admin", "UTF-8");
		String pwd = URLEncoder.encode("adminpwd", "UTF-8");
		
		StringBuilder tmp = new StringBuilder();
		tmp.append("mongodb://").append(account).append(":").append(pwd)
			.append("@localhost:27017");
		
	    String uri = tmp.toString();
	    
	    MongoClientSettings mcs = MongoClientSettings.builder().applyToSocketSettings(b -> 
	    	// 连接超时时间+读取超时时间, 默认30秒, 这里设置为三秒
	    	b.connectTimeout(3, TimeUnit.SECONDS)
	    		.readTimeout(3, TimeUnit.SECONDS);
	    )
	    .applyToClusterSettings(b -> b.serverSelectionTimeout(3, TimeUnit.SECONDS))
	    .applyConnectionString(new ConnectionString(uri)).build();
	    
	    mongoClient = MongoClients.create(mcs);
//	    System.out.println(uri);
	    
	    MongoDatabase database = mongoClient.getDatabase("Test");
	    MongoCollection<Document> collection = database.getCollection("test");
	    
	    while (true) 
	    	try 
	    		Document doc = collection.find().first();
	    		List<Document> loves = doc.getList("love", Document.class);
	    		<

以上是关于MongoDB的安装配置及使用(WIndows/Java)的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB的安装配置及使用(WIndows/Java)

MongoDB的安装配置及使用(WIndows/Java)

MongoDB简介及安装配置

MongoDB3.2.7安装及用户角色配置

MongoDB的「Linux」安装及基本使用

CentOS 6 使用 yum 安装MongoDB及服务器端配置