• Mongodb的基本使用及对接多数据源


    mongodb介绍


    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。


    MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。


    MongoDB是一个文档数据库。这里对比RDBMS来介绍Mongodb。


    传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB的collection对应关系型数据库里的表,但是集合中没有列、行和关系概念


    1、基本概念

    1.1、数据库:

    在Mongodb中,db表示数据库,对应RDBMS的数据库。

    'show dbs'
    可以查看所有数据库
    'use 数据库名称'
    表示使用指定数据库

    1.2、集合:

    集合Collections对应 RDBMS的表

    'show collections'
    可以查看当前db下所有集合

    1.3、文档:

    文档对应RDBMS的表中的数据

    db.'集合名称'.find();
    表示查询当前集合下所有文档数据。其中文档是以BSON进行存储,BSON是一种二进制序列化格式,用于在MongoDB中存储文档和进行远程过程调用。参考BSON介绍

    2、特性

    2.1、高性能:

    • 对嵌入式数据模型的支持减少了数据库系统上的I / O操作
    • 索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键

    2.2、丰富的查询语言:

    • MongoDB支持丰富的查询语言以支持读写操作(CRUD)
    • 数据聚合
    • 文本搜索和地理空间查询

    2.3、高可用:

    • MongoDB的复制工具(称为副本集)提供 自动故障转移 和 数据冗余。副本集是一组维护相同数据集合的 mongod实例,提供了冗余和提高了数据可用性。

    2.4、水平拓展:

    • MongoDB提供水平可伸缩性作为其核心 功能的一部分:数据分片切割将数据分布在一个集群的机器上。
    • 从3.4开始,MongoDB支持基于分片键创建数据区域。在平衡群集中,MongoDB仅将区域覆盖的读写定向到区域内的那些分片。

    2.5、支持多种存储引擎:

    • WiredTiger存储引擎(包括对静态加密的支持 )
    • 内存存储引擎
    • PS: MongoDB提供可插拔的存储引擎API,允许第三方为MongoDB开发存储引擎

    3、mongodb基本命令使用

    使用mongodb自带的mongodb Shell来学习mongodb提供的基本CRUD操作

    3.1、进入mongodb安装路劲的bin目录

    mongo --host 127.0.0.1 --port 27017 // 使用命令连接mongodb并使用mongodb Shell

    show dbs //查询所有数据库

    use mytest //使用指定的数据库

    db.myCollection01.insertOne( {x : 1} ); //创建文档{x : 1} 如果没有数据库和集合,那么会默认创建集合和数据库,并插入文档到集合中

    MongoDB中的所有写操作都是单个文档级别的原子操作。 有关MongoDB和原子性的更多信息,请参见原子性

    3.2、新增操作

    db.inventory.insertOne(
    { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
    ) //插入文档到集合inventory中,如果集合不存在,那么会默认创建集合

    db.inventory.insertMany([
    { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
    { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
    { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
    { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
    { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
    ]); //插入多条文档

    3.3、查询操作

    db.inventory.find( {} ) // SELECT * FROM inventory

    db.inventory.find( { status: "D" } ) // SELECT * FROM inventory WHERE status = "D"

    db.inventory.find( { status: { $in: [ "A", "D" ] } } ) // SELECT * FROM inventory WHERE status in ("A", "D")

    db.inventory.find( { status: "A", qty: { $lt: 30 } } ) // SELECT * FROM inventory WHERE status = "A" AND qty < 30

    db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } ) // SELECT * FROM inventory WHERE status = "A" OR qty < 30

    db.inventory.find( {
    status: "A",
    $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
    } ) // SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")

    3.4、删除操作

    db.inventory.deleteMany({}) // 从inventory收集中删除所有文档

    db.inventory.deleteMany({ status : "A" }) // 从状态字段等于“ A”的inventory集合中删除所有文档

    db.inventory.deleteOne( { status: "D" } ) // 删除状态为“ D”的第一个文档

    即使从集合中删除所有文档,删除操作也不会删除索引。

    3.5、修改操作

    先使用插入多条数据插入示例数据,在示例数据的基础上进行更新操作

    db.inventory.insertMany( [
    { item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
    { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
    { item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
    { item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
    { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
    { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
    { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
    { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
    { item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
    { item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }
    ] ); //插入多条示例文档

    db.inventory.updateOne(
    { item: "paper" },
    {
    $set: { "size.uom": "cm", status: "P" },
    $currentDate: { lastModified: true }
    }
    )
    // 使用$set 运算符将size.uom字段的值更新为“ cm”,将状态字段的值更新为“ P”,使用$currentDate运算符将lastModified字段的值更新为当前日期。 如果lastModified字段不存在,则$currentDate将创建该字段

    要替换_id字段以外的文档的全部内容,请将一个全新的文档作为第二个参数传递给db.collection.replaceOne()。

    在替换文档中,由于_id字段是不可变的,因此可以省略_id字段。如果确实包含_id字段,则它必须与当前值具有相同的值

    db.inventory.replaceOne(
    { item: "paper" },
    { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
    )//替换了inventory集合中的第一个文件,其中项为"paper":


    文档设置后,您将无法更新_id字段的值,也无法将现有文档替换为具有不同_id字段值的替换文档


    除以下情况外,MongoDB会在执行写操作后保留文档字段的顺序:
    • _id字段始终是文档中的第一个字段。
    • 包含字段名称renaming 的更新可能导致文档中字段的重新排序

    如果updateOne(), updateMany(), or replaceOne() 包含upsert:true,并且没有文档与指定的过滤器匹配,则该操作将创建一个新文档并将其插入。 如果存在匹配的文档,则该操作将修改或替换一个或多个匹配的文档。


    4、java操作mongodb


    Spring Data的MongoRepository和MongoTemplate。


    4.1、MongoRepository依次实现了PagingAndSortingRepository、CrudRepository、Spring Data的Repository
    • Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类
    • CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法
    • PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法
    • MongoRepository: 继承 PagingAndSortingRepository,实现一组 mongodb规范相关的方法 //自定义的 XxxxRepository 需要继承 MongoRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力(CURD的操作功能)

    MongoRepository的缺点是不够灵活,MongoTemplate正好可以弥补不足


    4.2、MongoTemplate采用了模板方法设计模式,封装了代码调用获取链接执行语句等操作。
    • MongoTemplate实现了interface MongoOperations。
    • MongoDB documents和domain classes之间的映射关系是通过实现了MongoConverter这个interface的类来实现的。
    • MongoTemplate提供了非常多的操作MongoDB的方法。 它是线程安全的,可以在多线程的情况下使用。
    • MongoTemplate实现了MongoOperations接口, 此接口定义了众多的操作方法如"find", "findAndModify", "findOne", "insert", "remove", "save", "update" and "updateMulti"等。
    • MongoTemplate转换domain object为DBObject,缺省转换类为MongoMappingConverter,并提供了Query, Criteria, and Update等流式API
    MongoTemplate的类结构如下:其中有两个重要的操作类

    MongoTemplate类结构


    MongoTemplate类结构

    • Criteria类:封装所有的语句,以方法的形式查询。
      Criteria类结构

    • Query类:将语句进行封装或者添加排序之类的操作。
      Query类结构

    从上面类结构可以知道使用 Query 构造方法,传入一个Criteria类,可以构建一个简单的过滤器去进行CRUD。
    下面介绍使用MongoTemplate进行简单的crud

    //yml配置
    spring:
      data:
        mongodb:
          uri: mongodb://localhost:27017/mytest
    
    //测试代码
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MongodbUtil {
    
    
        @Autowired
        private MongoTemplate mongoTemplate;
    //
    //    @Autowired
    //    private PersonRepository personRepository;
    
    
        /**
         * insert document
         *
         * {
         *     "name" : "cgg",
         *     "info": {
         *         "age" : 18
         *     }
         * }
         */
        @Test
        public void testInsert() {
            Map<String, Object> data = Maps.newHashMap();
            Map<String, Object> info = Maps.newHashMap();
            data.put("name", "cgg");
            info.put("age" , 18);
            data.put("info", info);
            mongoTemplate.insert(data, "inventory");
            System.out.println(mongoTemplate.findAll(Map.class, "inventory"));
        }
    
        /**
         * select * from inventory where status in ('A')
         */
        @Test
        public void testQuery() {
            Query query = new Query();
            query.addCriteria(Criteria.where("status").in("A"));
            mongoTemplate.executeQuery(query, "inventory", System.out::println);
        }
    
    
        /**
         * update inventory set qty = 55 where status in ('A')
         */
        @Test
        public void testUpdate() {
            Query query = new Query();
            query.addCriteria(Criteria.where("status").in("A"));
            Update update = new Update();
            update.set("qty", 55);
            mongoTemplate.updateMulti(query, update, "inventory");
            System.out.println(mongoTemplate.findAll(Map.class, "inventory"));
        }
    
        /**
         * delete from inventory  where name = 'cgg'
         */
        @Test
        public void testDelete() {
            Query query = new Query();
            query.addCriteria(Criteria.where("name").in("cgg"));
            mongoTemplate.remove(query, "inventory");
            testQuery();
        }
    
    }
    

    5、mongodb客户端

    mongodb客户端有很多,这里推荐大家使用Robo,支持查看各种语言的查询语句、结果集转换,筛选查询,查看查询计划等等

    Robo客户端

    Robo下载地址Robo studio


    6、mongodb对接多数据源

    Springboot项目整合mongodb多数据源配置

    #yml配置
    spring:
      data:
        mongodb:
          one:
            uri: mongodb://localhost:27017/mytest
          two:
            uri: mongodb://localhost:27018/mytest
    
    
    /**
     * mongodb 多数据源属性配置类
     *
     * @author cgg
     * @since 2021/07/21
     * @version 1.0
     */
    @Configuration
    public class MongoConfiguration {
    
        @Bean(name = "oneMongoProperties")
        @Primary
        @ConfigurationProperties(prefix = "spring.data.mongodb.one")
        public MongoProperties masterMongoProperties() {
            return new MongoProperties();
        }
    
        @Bean(name = "twoMongoProperties")
        @ConfigurationProperties(prefix = "spring.data.mongodb.two")
        public MongoProperties twoMongoProperties() {
            return new MongoProperties();
        }
    
    
    }
    
    /**
     * mongodb://localhost:27017/mytest 数据源配置类 完成MongoTemplate的注入
     *
     * @author cgg
     * @since 2021/07/21
     * @version 1.0
     */
    @Configuration
    @EnableMongoRepositories(mongoTemplateRef = "oneMongo")
    public class OneMongoTemplateConf {
    
        private final MongoProperties mongoProperties;
    
        public OneMongoTemplateConf(@Qualifier("oneMongoProperties") MongoProperties mongoProperties) {
            this.mongoProperties = mongoProperties;
        }
    
        @Bean(name = "oneMongo")
        @Primary
        public MongoTemplate mongoTemplate() {
            return new MongoTemplate(mongoDatabaseFactory(mongoProperties));
        }
    
        @Bean(name = "oneMongoFactory")
        @Primary
        public MongoDatabaseFactory mongoDatabaseFactory(MongoProperties mongoProperties) {
            return new SimpleMongoClientDatabaseFactory(mongoProperties.getUri());
        }
    
    
    }
    
    
    /**
     *
     * mongodb://localhost:27018/mytest 数据源配置类 完成MongoTemplate的注入
     *
     * @author cgg
     * @since 2021/07/21
     * @version 1.0
     */
    @Configuration
    @EnableMongoRepositories(mongoTemplateRef = "twoMongo")
    public class TwoMongoTemplateConf {
    
        private final MongoProperties mongoProperties;
    
        public TwoMongoTemplateConf(@Qualifier("twoMongoProperties") MongoProperties mongoProperties) {
            this.mongoProperties = mongoProperties;
        }
    
        @Bean(name = "twoMongo")
        public MongoTemplate mongoTemplate() {
            return new MongoTemplate(mongoDatabaseFactory(mongoProperties));
        }
    
        @Bean(name = "twoMongoFactory")
        public MongoDatabaseFactory mongoDatabaseFactory(MongoProperties mongoProperties) {
            return new SimpleMongoClientDatabaseFactory(mongoProperties.getUri());
        }
    
    
    }
    
    /**
     * mongodb 多数据源测试
     *
     * @author cgg
     * @since 2021/07/21
     * @version 1.0
     */
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MongoTest {
    
        @Autowired
        @Qualifier("oneMongo")
        private MongoTemplate oneMongoTemplate;
    
    
        @Autowired
        @Qualifier("twoMongo")
        private MongoTemplate twoMongoTemplate;
    
    
        /**
         * 向 localhost:27017/mytest插入数据
         */
        @Test
        public void testOneMongoInsert() {
            Map<String, Object> data = Maps.newHashMap();
            Map<String, Object> info = Maps.newHashMap();
            data.put("name", "cgg");
            data.put("attr", "one");
            info.put("age" , 18);
            data.put("info", info);
            oneMongoTemplate.insert(data, "inventory_27017");
            System.out.println(oneMongoTemplate.findAll(Map.class, "inventory_27017"));
        }
    
        /**
         * 向 localhost:27018/mytest插入数据
         */
        @Test
        public void testTwoMongoInsert() {
            Map<String, Object> data = Maps.newHashMap();
            Map<String, Object> info = Maps.newHashMap();
            data.put("name", "cgg");
            data.put("attr", "two");
            info.put("age" , 18);
            data.put("info", info);
            twoMongoTemplate.insert(data, "inventory_27018");
            System.out.println(twoMongoTemplate.findAll(Map.class, "inventory_27018"));
        }
    
    }
    
    

    多数据源配置,测试结果展示

    多数据源操作结果


    7、MongoDB CRUD概念



    上面介绍了mongodb的入门使用,关于mongodb,还有数据模型、事务、索引、聚合、安全、复制、分片、管理、存储等等。下一篇将着重介绍Mongodb的更多使用和特性。


  • 相关阅读:
    程序员学习视频教程汇总
    分享一个单机软件试用期计时思路
    C# XML转Json Json转XML XML 转对象 对象转XML
    C# 数独 解法
    C# 炸弹人 winform版
    胃食管反流疾病认识总结
    C# Datagridview combox列 初始化颜色
    C# WPF 坦克大战
    高分辨率食道测压(HRM)
    C# wpf 使用 polyline 做一个贪吃蛇游戏的小蛇移动吃食部分功能
  • 原文地址:https://www.cnblogs.com/wa1l-E/p/15037333.html
Copyright © 2020-2023  润新知