• 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
    
    • 1

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

    运行结果

    接下来就可以连接上 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

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

    mongod --config 配置文件地址
    # 或
    mongod -f 配置文件地址
    # 例如
    mongod --config C:/config.yml
    
    • 1
    • 2
    • 3
    • 4
    • 5


    安装服务

    –install 参数安装服务

    例如

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

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

    mongod --config "C:/config.yml" --install
    
    • 1
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    命令

    # 启动服务
    net start MongoDB
    # 关闭服务
    net stop MongoDB
    # 移除服务
    mongod --remove
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

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

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

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



    创建用户

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

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

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

    MONGOSH

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

    # 进入admin数据库
    use admin
    # 创建超级管理员用户 - 拥有所有数据库的所有权限
    db.createUser({
    	user:"admin",
    	pwd:"adminpwd",
    	roles:[{role:"root",db:"admin"}],
    	# 可选, 自定义信息
    	customData: {name : "Shendi"}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

    在配置文件添加

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

    最后,重启 MongoDB/服务

    net stop mongodb
    net start mongodb
    
    • 1
    • 2

    图形化界面

    重新打开,或 disconnect

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

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

    设置账号登录

    命令行则使用

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

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

    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("用户名")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8


    Java使用

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


    Maven导入

    <dependencies>
        <dependency>
            <groupId>org.mongodbgroupId>
            <artifactId>mongodb-driver-syncartifactId>
            <version>4.7.2version>
        dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Gradle导入

    dependencies {
      implementation 'org.mongodb:mongodb-driver-sync:4.7.2'
    }
    
    • 1
    • 2
    • 3

    普通项目的话,除了要引入 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 = "";
        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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    database为数据库,collection类似于表

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

    例如

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

    参数带有特殊字符则需要进行 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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

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

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

    数据结构 - Shendi

    代码及结果如下

    代码+结果 - Shendi

    其中 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());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14


    插入数据

    插入数据使用 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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    新增数据 - Shendi

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

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

    insertMany函数则接收 List

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

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


    例如

    InsertOneResult one = collection.insertOne(d);
    one.getInsertedId();
    
    InsertManyResult many = collection.insertMany(list);
    many.getInsertedIds();
    
    • 1
    • 2
    • 3
    • 4
    • 5


    修改数据

    使用 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());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    数据结构如下

    修改数据 - Shendi

    运行后,结果如下

    修改数据结果 - Shendi

    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());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    最终结果变为

    替换数据结果 - Shendi



    删除数据

    使用 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());
    
    • 1
    • 2
    • 3
    • 4

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



    设置数据过期时间

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

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

    新建TTL索引 - Shendi

    或通过命令行的方式

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

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

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

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

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

    不包含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;
    
    /**
     * 测试
     * 
    * @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); for (Document love : loves) { System.out.println("爱好:" + love.getString("name") + ", 打分:" + love.getString("scope")); } Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67


    内存为什么只增不减?

    新版默认使用 WiredTiger 存储引擎,经过测试,内存只增不减(删除数据甚至删库也不会减少)

    默认占用内存:(电脑总内存-1) * 50%

    例如 4G 默认占用 (4-1)*50% = 1.5G

    而且测试时,增加1万数据,后删除1万数据,再增加1万数据,内存不会重复利用,等于占用了两万数据的内存

    据说是将内存操作丢给操作系统处理,当其他应用内存不够时才会减少

    可以通过以下配置指定最小内存,指定后虽然内存同样只增不减但可重复利用

    # 指定内存 1代表1G,最小0.25
     wiredTiger:
      engineConfig:
       cacheSizeGB: 0.25
    
    • 1
    • 2
    • 3
    • 4

    例如插入1w 数据占用100MB内存,删除后再插入 1W 数据仍然占用 100MB

    插入10W数据占用 1GB,删除掉仍然占用 1GB,即使删库,数据超过 cacheSizeGB 指定的内存大小如果还有可用内存则会继续占用

  • 相关阅读:
    5.Servlet
    CPU卡学习
    第17集丨如何为成功“保鲜”
    java教程
    计算机毕业设计hadoop+spark知识图谱课程推荐系统 课程预测系统 课程大数据 课程数据分析 课程大屏 mooc慕课推荐系统 大数据毕业设计
    Mysql语法四:索引查找和了解何为事务
    Node.js vs. Spring Boot:Hello World 性能对决,谁更快一点?
    Kubernetes通过HostAliases自定义hosts
    报价33万的极星电动车,一组电池就高达40万?
    [附源码]计算机毕业设计学习帮扶网站设计与实现Springboot程序
  • 原文地址:https://blog.csdn.net/qq_41806966/article/details/127935074