暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java项目笔记之MongoDB

java学途 2021-06-21
1323


不点蓝字,我们哪来故事?



MongoDB

目标

  • 了解MongoDB数据库结构

  • 掌握基本的CRUD和高级查询操作

  • 掌握Spring Data MongoDB的使用


MongoDB介绍

简介

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

https://baijiahao.baidu.com/s?id=1628146397605671081&wfr=spider&for=pc

特点

  • 高性能

  • 易部署

  • 易使用

  • 非常方便的存储数据

对比MySQL

目前环境下,只要对事务要求不高的业务都能被MongoDB所取代,属于及其热门的NoSQL数据库

数据库结构

MongoDB属于NoSQL数据库,自然也是没有表相关概念的,该数据库存储使用的是集合,集合中存储的是文档(树状结构数据)


安装和连接

安装客户端和服务器

根据安装包的提示操作,选择自定义安装,其中只安装服务端和客户端即可

最后千万不要勾选

连接服务器

安装好后,默认会启动MongoDB服务器,可以在服务列表中找到MongoDB Server查看是否处于运行状态,已经处于运行状态则直接进入安装目录/Server/bin,运行mongo.exe,出现以下画面表示安装成功了

补充:MongoDB默认端口27017


基本操作

MongoDB的操作有很多,需要掌握更多技能的同学可以查询在线的文档,这里主要是讲这么去学习这个工具

在线文档教程: https://www.runoob.com/mongodb/mongodb-tutorial.html

语法

     show dbs: 查询所有数据库
    use 数据库名: 创建并且选中数据库,数据库已经存在则直接选中
    db: 查询当前选择的数据库
    db.dropDatabase(): 删除当前选中的数据库
    show collections: 查询当前库中的集合
    db.createCollection("集合名"): 创建集合
    db.集合名.drop(): 删除集合

    注意: db.集合名 == db.getCollection("集合名")


    新增操作

    数据类型

    在MongoDB中支持以下的数据类型

       String(字符串): mongodb中的字符串是UTF-8有效的 
      Integer(整数): 存储数值。整数可以是32位或64位,具体取决于您的服务器
      Boolean(布尔): 存储布尔(true/false)值
      Double(双精度): 存储浮点值
      Arrays(数组): 将数组或列表或多个值存储到⼀个键中
      Timestamp(时间戳): 存储时间戳
      Object(对象): 嵌⼊式⽂档
      Null (空值): 存储Null值
      Symbol(符号): 与字符串相同,⽤于具有特定符号类型的语⾔
      Date(⽇期): 以UNIX时间格式存储当前⽇期或时间
      Object ID(对象ID) : 存储⽂档ID
      Binary data(⼆进制数据): 存储⼆进制数据
      Code(代码): 将JavaScript代码存储到⽂档中
      Regular expression(正则表达式): 存储正则表达式


      语法

      往集合中新增文档,当集合不存在时会自动先创建集合,再往集合中添加文档,但是不要依赖自动创建集合的特性

         db.集合名.insert( 文档 ) : 往集合中插入一个文档
        db.集合名.find({}): 查询集合中所有文档

        当操作成功时,集合会给文档生成一个_id字段,该字段就是文档的主键,也能在插入数据时自己指定该字段的值,但是不建议这样做


        实例

           //插入员工对象
          db.users.insert({id: 1, name: "bunny", age: 20})
          db.users.insert({id: 2, name: "逍遥", age: 18})

          注意:直接写数字默认是Duble类型,其实在使用时是不影响的,仅仅只是类型问题


          更新操作

          修改集合中已经存在的文档

          语法

             db.集合名.update(
            <query>,
            <update>,
            {
            upsert: <boolean>,
            multi: <boolean>,
            writeConcern: <document>
            }
            )

            简化方法:
            更新1个:db.集合名.updateOne( ... )
            更新所有:db.集合名.updateMany( ... )

            参数说明:

            • query : update的查询条件,类似sql update查询内where后面的。

            • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的

            • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。

            • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

            • writeConcern :可选,抛出异常的级别


            实例

               //把一个带有name=逍遥的文档,修改其age值为30
              db.employees.updateOne({name: "逍遥"}, {$set: {age: 30}})

              //修改所有name=逍遥的文档,修改其name=bunny,age=20
              db.employees.updateMany({name: "逍遥"}, {$set: {name: "bunny", age: 30}})

              //修改所有的文档,修改其name=xxx,age=10
              db.employees.updateMany({}, {$set: {name: "xxx", age: 10}})


              删除操作

              删除集合中的文档

              语法

                 db.集合名.remove(
                <query>,
                {
                justOne: <boolean>,
                writeConcern: <document>
                }
                )

                简化方法:
                删除1个:db.集合名.deleteOne( ... )
                删除所有:db.集合名.deleteMany( ... )

                参数说明:

                • query :(可选)删除的文档的条件。

                • justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。

                • writeConcern :(可选)抛出异常的级别

                实例

                   //删除_id=xxx的文档
                  db.users.deleteOne({_id: ObjectId("xxx")})

                  //删除所有带有name=bunny的文档
                  db.users.deleteMany({name: "bunny"})

                  //删除当前数据库中所有文档
                  db.users.deleteMany({})


                  查询操作

                  语法

                     db.集合名.find(queryprojection)
                    • query :可选,使用查询操作符指定查询条件

                    • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)

                    实例

                       //查询所有文档
                      db.users.find({})

                      排序查询

                         db.users.find({}).sort({字段: 1}) -> 按照字段升序排列
                        db.users.find({}).sort({字段: -1}) -> 按照字段降序排列

                        分页查询

                           sikp(num): 跳过num个文档,相当于start
                          limit(num): 限制显示num个文档,相当于pageSize
                          如:
                          db.users.find({}).skip(num).limit(num)

                          需求:按照年龄降序排列,查询第2页,每页显示3


                          高级查询

                          高级查询在数据库中是经常使用的,在MongoDB中也同样是提供了高级查询的功能

                          等值

                             语法 -> find({字段: 值})

                            比较查询

                               语法 -> find({字段: {比较操作符: 值, ...}})

                              比较操作符

                              • (>) 大于 - $gt

                              • (<) 小于 - $lt

                              • (>=) 大于等于 - $gte

                              • (<= ) 小于等于 - $lte

                              • (!=) 不等 - $ne

                              • 集合运算 - $in    如:{name: {$in: ["xiaoyao","bunny"]}}

                              • 判断存在 - $exists    如:{name: {$exists:true}}

                              逻辑查询

                                语法 -> find({列:{逻辑操作符: [条件1, 条件2, ...]}})

                                逻辑操作符

                                • (&&) 与 - $and

                                • (||) 或 - $or

                                • (!) 非 - $not

                                模糊查询

                                MongoDB的模糊查询使用的是正则表达式的语法     如:{name: {$regex: ^.*keyword.*$/}}

                                实际上MongoDB也是不擅长执行模糊查询的,在实际开发中也是不使用的,该功能了解即可

                                  需求1:查询所有name=逍遥的文档
                                  需求2:查询所有name=bunny或者age<30的文档
                                  需求3:查询所有name含有wang并且30<=age<=32的文档
                                     //需求1:查询所有name=逍遥的文档
                                    db.users.find({name:"逍遥"})
                                    //需求2:查询所有name=bunny或者age<30的文档
                                    db.users.find({$or:[{name:"bunny"},{age:{$lt:30}}]})
                                    //需求3:查询所有name含有wang并且30<=age<=32的文档
                                    db.users.find({$and:[{name:{$regex:/^.*wang.*$/}},{age:{$gte:30,$lte:32}
                                    }]})


                                    设置用户

                                    以下操作必须在cmd命令行中操作,执行以下命令

                                       1.选中admin数据库
                                      use admin
                                      2.往里面添加一个超级管理员账号
                                      db.createUser({user:"root", pwd: "admin", roles:["root"]})
                                      user:账号 pwd:密码 roles:角色->root超级管理员

                                      修改MongoDB的配置文件:安装目录/Server/bin/mongod.cfg

                                         #约在29行位置,配置开启权限认证
                                        security:
                                        authorization: enabled

                                        完成上面配置后重启服务器

                                        在登录时就必须要输入密码,否则不能执行任何的命令

                                        Spring Data MongoDB

                                        准备环境

                                           <parent>
                                          <groupId>org.springframework.boot</groupId>
                                          <artifactId>spring-boot-starter-parent</artifactId>
                                          <version>2.1.3.RELEASE</version>
                                          </parent>

                                          <properties>
                                          <java.version>1.8</java.version>
                                          </properties>

                                          <dependencies>
                                          <dependency>
                                          <groupId>org.springframework.boot</groupId>
                                          <artifactId>spring-boot-starter</artifactId>
                                          </dependency>

                                          <dependency>
                                          <groupId>org.springframework.boot</groupId>
                                          <artifactId>spring-boot-starter-test</artifactId>
                                          <scope>test</scope>
                                          </dependency>

                                          <dependency>
                                          <groupId>org.projectlombok</groupId>
                                          <artifactId>lombok</artifactId>
                                          </dependency>

                                          <!--spring boot data mongodb-->
                                          <dependency>
                                          <groupId>org.springframework.boot</groupId>
                                          <artifactId>spring-boot-starter-data-mongodb</artifactId>
                                          </dependency>
                                          </dependencies>

                                          <build>
                                          <plugins>
                                          <plugin>
                                          <groupId>org.springframework.boot</groupId>
                                          <artifactId>spring-boot-maven-plugin</artifactId>
                                          </plugin>
                                          </plugins>
                                          </build>


                                          配置连接参数

                                             # application.properties
                                            # 配置数据库连接
                                            #格式: mongodb://账号:密码@ip:端口/数据库?认证数据库
                                            spring.data.mongodb.uri=mongodb://root:admin@localhost/mongotest?authSource=admin

                                            # 配置MongoTemplate的执行日志
                                            logging.level.org.springframework.data.mongodb.core=debug

                                            domain

                                               @AllArgsConstructor
                                              @NoArgsConstructor
                                              @Setter@Getter@ToString
                                              @Document("users") //设置文档所在的集合
                                              public class User {
                                              @Id //文档的id使用ObjectId类型来封装,并且贴上@Id注解
                                              private ObjectId _id;

                                              private Long id;
                                              private String name;
                                              private Integer age;
                                              }


                                              MongoRepository

                                              该接口对MongoDB数据的常用操作进行了封装,我们只需要写个接口去继承该接口就能直接拥有的CRUD等基本操作,再学习下JPA的方法命名规范,可以毫不费力的完成各种复杂的高级操作

                                                 /**
                                                * 自定义一个接口继承MongoRepository,
                                                * 泛型1:domain类型
                                                * 泛型2:文档主键类型
                                                * 贴上@Repository注解,底层会创建出动态代理对象,交给Spring管理
                                                */
                                                @Repository
                                                public interface UserMongoRepository extends MongoRepository<User, ObjectId> {
                                                // 使用Spring Data命名规范做高级查询
                                                List<User> findByName(String name);
                                                }


                                                Spring Data方法命名规范

                                                关键字例子JPQL
                                                AndfindByNameAndAge(String name, Integer age)where name = ? and age = ?
                                                OrfindByNameOrAge(String name, Integer age)where name = ? or age = ?
                                                IsfindByName(String name)where name = ?
                                                BetweenfindByAgeBetween(Integer min, Integer max)where age between ? and ?
                                                LessThanfindByAgeLessThan(Integer age)where age < ?
                                                LessThanEqualfindByAgeLessThanEqual(Integer age)where age <= ?
                                                GreaterThanfindByAgeGreaterThan(Integer age)where age > ?
                                                GreaterThanEqualfindByAgeGreaterThanEqual(Integer age)where age >= ?
                                                After等同于GreaterThan
                                                Before等同于LessThan
                                                IsNullfindByNameIsNull()where name is null
                                                IsNotNullfindByNameIsNotNull()where name is not null
                                                LikefindByNameLike(String name)where name like ?
                                                NotLikefindByNameNotLike(String name)where name not like ?
                                                StartingWithfindByNameStartingWith(String name)where name like '?%'
                                                EndingWithfindByNameEndingWith(String name)where name like '%?'
                                                ContainingfindByNameContaining(String name)where name like '%?%'
                                                OrderByXx[desc]findByIdOrderByXx[Desc] (Long id)where id = ? order by Xx [desc]
                                                NotfindByNameNot(String name)where name != ?
                                                InfindByIdIn(List<Long> ids)where id in ( ... )
                                                NotInfindByIdNotIn(List<Long> ids)where id not in ( ... )
                                                TruefindByXxTrue()where Xx = true
                                                FalsefindByXxFalse()where Xx = false
                                                IgnoreCasefindByNameIgnoreCase(String name)where name = ? (忽略大小写)

                                                实例代码

                                                   @Autowired
                                                  private UserMongoRepository repository;

                                                  // 插入/更新一个文档
                                                  @Test
                                                  public void testSaveOrUpdate() throws Exception {
                                                  User user = new User(null, 5L, "bunny", 20);
                                                  // 主键为null则新增,不为null则更新
                                                  repository.save(user);
                                                  }

                                                  // 删除一个文档
                                                  @Test
                                                  public void testDelete() throws Exception {
                                                  repository.deleteById(new ObjectId("xxx"));
                                                  }

                                                  // 查询一个文档
                                                  @Test
                                                  public void testGet() throws Exception {
                                                  Optional<User> optional = repository.findById(new ObjectId("xxx"));
                                                  optional.ifPresent(System.err::println);
                                                  }

                                                  // 查询所有文档
                                                  @Test
                                                  public void testList() throws Exception {
                                                  // 查询所有文档
                                                  List<User> list = repository.findAll();
                                                  list.forEach(System.err::println);
                                                  }

                                                  MongoTemplate

                                                  该对象有SpringBoot完成了自动配置,存入Spring容器中,我们直接注入就可以使用了,依靠该对象能完成任何的MongoDB操作,一般和MongoRepository分工合作,多数用于复杂的高级查询以及底层操作

                                                     //注入MongoTemplate
                                                    @Autowired
                                                    private MongoTemplate template;

                                                    条件限定

                                                    Query对象用于封装查询条件,配合Criteria一起使用,来完成各种条件的描述

                                                       //一个Criteria对象可以理解为是一个限定条件
                                                      Criteria.where(String key).is(Object val); //设置一个等值条件
                                                      Criteria.orOperator(Criteria ...); //设置一组或的逻辑条件

                                                      //模糊查询(了解)
                                                      Criteria.where(String key).regex(String regex); //使用正则表达式匹配查询

                                                      注意:Criteria对象可以由其静态方法和构造器获取
                                                      Criteria封装了所有对条件的描述,常见的有以下方法
                                                      lt / lte / gt / gte / ne / ...

                                                      最后通过Query对象的addCriteria把条件封装到Query对象中

                                                         Query对象.addCriteria(Criteria criteria); //添加查询条件
                                                        Query对象.skip(start).limit(pageSize); //分页查询

                                                        API方法

                                                           //根据条件查询集合中的文档
                                                          List<T> mongoTemplate.find(Query query, Class<T> type, String collectionName);

                                                          实例代码

                                                             @Autowired
                                                            private MongoTemplate mongoTemplate

                                                            // 分页查询文档,显示第2页,每页显示3个,按照id升序排列
                                                            @Test
                                                            public void testQuery1() throws Exception {
                                                            // 创建查询对象
                                                            Query query = new Query();
                                                            // 设置分页信息
                                                            query.skip(3).limit(3);
                                                            // 设置排序规则
                                                            query.with(new Sort(Sort.Direction.ASC,"id"));

                                                            List<User> list = mongoTemplate.find(query, User.class, "users");
                                                            list.forEach(System.err::println);
                                                            }

                                                            // 查询所有name为bunny的文档
                                                            @Test
                                                            public void testQuery2() throws Exception {
                                                            // 构建限制条件 {"name": "bunny"}
                                                            Criteria criteria = Criteria.where("name").is("bunny");
                                                            // 创建查询对象
                                                            Query query = new Query();
                                                            // 添加限制条件
                                                            query.addCriteria(criteria);

                                                            List<User> list = mongoTemplate.find(query, User.class, "users");
                                                            list.forEach(System.err::println);
                                                            }

                                                            // 查询所有name为bunny或者age<30的文档
                                                            @Test
                                                            public void testQuery3() throws Exception {
                                                            // 构建限制条件 { "$or": [{"name": "bunny"}, {"age": {"$lt": 30}}] }
                                                            Criteria criteria = new Criteria().orOperator(
                                                            Criteria.where("name").is("bunny"),
                                                            Criteria.where("age").lt(30)
                                                            );
                                                            // 创建查询对象
                                                            Query query = new Query();
                                                            // 添加限制条件
                                                            query.addCriteria(criteria);

                                                            List<User> list = mongoTemplate.find(query, User.class, "users");
                                                            list.forEach(System.err::println);
                                                            }

                                                            // 查询所有name含有wang并且30<=age<=32的文档
                                                            @Test
                                                            public void testQuery4() throws Exception {
                                                            // 构建限制条件 { "$and" : [{"name": {"$regex": ".*wang.*"} }, {"age": {"$gte": 30, "$lte": 32 } }] }
                                                            Criteria criteria = new Criteria().andOperator(
                                                            Criteria.where("name").regex(".*wang.*"),
                                                            Criteria.where("age").gte(30).lte(32)
                                                            );
                                                            // 创建查询对象
                                                            Query query = new Query();
                                                            // 添加限制条件
                                                            query.addCriteria(criteria);

                                                            List<User> list = mongoTemplate.find(query, User.class, "users");
                                                            list.forEach(System.err::println);
                                                            }





                                                            java学途

                                                            只分享有用的Java技术资料 

                                                            扫描二维码关注公众号

                                                             


                                                            笔记|学习资料|面试笔试题|经验分享 

                                                            如有任何需求或问题欢迎骚扰。微信号:JL2020aini

                                                            或扫描下方二维码添加小编微信

                                                             




                                                            小伙砸,欢迎再看分享给其他小伙伴!共同进步!




                                                            文章转载自java学途,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                            评论