【MongoDB详细步骤】(内附源码)

第01章-MongoDB

1、安装和启动(docker方式)

1.1、拉取镜像

docker pull mongo:4.4.8

1.2、创建和启动容器

docker run -d --restart=always -p 27017:27017 --name atguigu_syt_mongo -v /atguigu/syt/mongo/data/db:/data/db mongo:4.4.8 --auth

常见问题:以下IPv4问题会导致无法远程链接redis服务

image-20230313182547232

解决方案:

#修改配置文件:
vim /usr/lib/sysctl.d/00-system.conf
#追加
net.ipv4.ip_forward=1
#接着重启网络
systemctl restart network

1.3、进入容器

docker exec -it atguigu_syt_mongo /bin/bash

1.4、进入MongoDB客户端

mongo

1.5、创建超级用户

show dbs
use admin
db.createUser({ user: "root" , pwd: "123456", roles: ["root"]})

1.6、登录超级用户

db.auth("root","123456")

1.7、基本命令

db.version() #当前db版本
db.getMongo() #查看当前db的链接机器地址
db.help() #帮助
quit() #退出命令行

常见问题

mongodb一直重启问题

mongo 容器 Restarting (62) 2 seconds ago

主要原因:新版本4.4的MongoDB 和之前安装的MongoDB (最新版)的数据存在冲突。

解决方案:因此删除之前MongoDB 的数据目录即可。

例如数据路径是: /atguigu/syt/mongo/data/db,直接rm -r /atguigu/syt/mongo/data/db/*

2、客户端远程远程连接

资料:资料>mongodb客户端>mongodb-compass-1.35.0-win32-x64.zip

解压并启动 mongodb-compass-1.35.0-win32-x64.zip

客户端连接:

image-20230316193003295

3、MongoDB 概念

3.1、什么是MongoDB

MongoDB 是在2007年由DoubleClick公司的几位核心成员开发出的一款分布式文档数据库,由C++语言编写。

目的是为了解决数据大量增长的时候系统的可扩展性和敏捷性。MongoDB要比传统的关系型数据库简单很多。

在MongoDB中数据主要的组织结构就是数据库、集合和文档,文档存储在集合当中,集合存储在数据库中。

MongoDB中每一条数据记录就是一个文档,数据结构由键值(key=>value)对组成

文档类似于 JSON 对象,它的数据结构被叫做BSON(Binary JSON)。

img

下表将帮助您更容易理解MongoDB中的一些概念:

RDBMS MongoDB
数据库 数据库
表格 集合
文档
字段
表联合 嵌入文档
主键 _id

3.2、MongoDB适用场景

MongoDB不需要去明确指定一张表的具体结构,对字段的管理非常灵活,有很强的可扩展性。

支持高并发、高可用、高可扩展性,自带数据压缩功能,支持海量数据的高效存储和访问。

支持基本的CRUD、数据聚合、文本搜索和地理空间查询功能。

适用场景:

  • 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  • 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。
  • 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
  • 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。

例如:

弹幕、直播间互动信息、朋友圈信息、物流场景等

不适用场合:

  • 高度事务性系统:例如银行系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
  • 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。

4、数据库操作

4.1、创建数据库

如果数据库不存在,则创建数据库,否则切换到指定数据库。

use test

4.2、查看当前数据库

db.getName()

4.3、显示当前数据库状态

db.stats()

4.4、删除当前数据库

db.dropDatabase()

5、集合操作

5.1、创建集合

db.createCollection("User")

5.2、删除集合

db.User.drop()

6、文档操作

文档是一组键值(key-value)对。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

需要注意的是:

1、MongoDB区分类型和大小写。

2、MongoDB的文档不能有重复的键。

6.1、insert

向User集合插入一条记录。可以预先使用createCollection方法创建集合,也可以不创建集合,直接插入数据,那么集合会被自动创建

db.User.insert({name:'zhangsan',age:21,sex:true})

6.2、query

查询当前User集合中所有的记录

db.User.find()

查询当前User集合中name是zhangsan的记录

db.User.find({name:"zhangsan"})

6.3、update

只更新匹配到的第一条记录

db.User.update({age:21}, {$set:{name:100}}) 

更新匹配到的所有记录

db.User.update({age:21}, {$set:{age:99}}, {multi: true})

6.4、remove

移除一个文档

db.User.remove(id)

移除所有文档

db.User.remove({}) 

更多命令参考:https://www.runoob.com/mongodb/mongodb-tutorial.html

第02章-SpringBoot集成MongoDB

spring-data-mongodb提供了MongoTemplateMongoRepository两种方式访问mongodb,MongoRepository操作简单,MongoTemplate操作灵活,我们在项目中可以灵活使用这两种方式操作mongodb。

1、集成spring-data-mongodb

1.1、添加用户

如果想在springboot中访问MongoDB,需要再创建一个非root用户。首先使用超级用户账号登录,然后创建数据库yygh,在yygh下创建一个用户:

use syt
db.createUser({user: "atguigu",pwd: "123456",roles: ["readWrite"]})

客户端连接:

image-20230316192836686

1.2、引入依赖

在service-hosp中引入依赖

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

1.3、添加MongoDB配置

在service-hosp中的application-dev.yml文件中添加配置

spring:
  data:
    mongodb:
      database: syt
      host: 192.168.100.101
      password: '123456'
      port: 27017
      username: atguigu

打印mongodb命令的日志

logging:
  level:
    root: info
    org:
      mongodb:
        driver:
          protocol:
            command: debug
  file:
    path: hosp

1.4、添加实体

test目录添加com.atguigu.syt.hosp.mongo包,添加User类

package com.atguigu.syt.hosp.mongo;

import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

@Data
@Document("user") //指定mongodb中的集合名字
public class User {

    @Id
    private ObjectId id;
    private String name;
    private Integer age;
    private String email;
    private Date createDate;
}

2、MongoRepository

2.1、添加Repository类

test目录添加UserRepository

package com.atguigu.syt.hosp.mongo;
public interface UserRepository extends MongoRepository<User, ObjectId> {
    
    
}

2.2、创建测试类

test目录创建测试类:MongoRepositoryTest

package com.atguigu.syt.hosp.mongo;

@SpringBootTest
public class MongoRepositoryTest {

    @Resource
    private UserRepository userRepository;

    //插入
    @Test
    public void testCreateUser(){

        User user = new User();
        user.setName("小谷");
        user.setAge(19);
        user.setCreateDate(new Date());
        userRepository.save(user);
    }

    //查询所有
    @Test
    public void testFindAll(){
        List<User> userList = userRepository.findAll();
        System.out.println(userList);
    }

    //根据id查询
    @Test
    public void testFindById(){

        Optional<User> optional = userRepository.findById(
            new ObjectId("6412fa11fa5cdd0300a2d4e4")
        );
        boolean present = optional.isPresent();
        if(present){
            User user = optional.get();
            System.out.println(user);
        }
    }

    //条件查询
    @Test
    public void testFindAllExample(){

        User user = new User();
        user.setAge(19);
        Example<User> example = Example.of(user);
        List<User> userList = userRepository.findAll(example);
        System.out.println(userList);
    }

    //排序查询
    @Test
    public void testFindAllSort(){
        Sort sort = Sort.by(Sort.Direction.DESC, "age");
        List<User> userList = userRepository.findAll(sort);
        System.out.println(userList);
    }

    //分页查询
    @Test
    public void testFindAllPage(){

        PageRequest pageRequest = PageRequest.of(0, 10);
        Page<User> page = userRepository.findAll(pageRequest);
        int totalPages = page.getTotalPages();
        List<User> userList = page.getContent();
        System.out.println(userList);
        System.out.println(totalPages);
    }

    //更新
    @Test
    public void testUpdateUser(){

        //注意:先查询,再更新
        Optional<User> optional = userRepository.findById(
                new ObjectId("6412fa11fa5cdd0300a2d4e4")
        );
        if(optional.isPresent()){
            User user = optional.get();
            user.setAge(100);
            //user中包含id,就会执行更新
            userRepository.save(user);
            System.out.println(user);
        }
    }

    //删除
    @Test
    public void testDeleteUser(){
        userRepository.deleteById(
                new ObjectId("6412fa11fa5cdd0300a2d4e4")
        );
    }
}

3、SpringData方法规范

3.1、方法规范说明

我们只需要继承MongoRepository类,按照Spring Data规范定义接口方法就可以。

1、 查询方法以find | read | get开头

2、 涉及条件查询时,条件的属性用条件关键字连接

3、条件属性首字母需要大写

img

img

3.2、定义接口方法

package com.atguigu.syt.hosp.mongo;

public interface UserRepository extends MongoRepository<User, ObjectId> {

    List<User> findByName(String name);
    List<User> findByNameLike(String name);
    List<User> findByNameAndAge(String name, Integer age);
}

3.3、测试

@Test
public void testFindByName() {
    List<User> users = userRepository.findByName("test");
    System.out.println(users);
}

@Test
public void testFindByNameLike() {
    List<User> users = userRepository.findByNameLike("e");
    System.out.println(users);
}

@Test
public void testFindByNameAndAge() {
    List<User> users = userRepository.findByNameAndAge("test", 20);
    System.out.println(users);
}

4、MongoTemplate

test目录创建测试类:MongoTemplateTest

package com.atguigu.syt.hosp.mongo;

@SpringBootTest
public class MongoTemplateTest {

    @Resource
    private MongoTemplate mongoTemplate;

    //添加
    @Test
    public void testCreateUser(){
        User user = new User();
        user.setAge(20);
        user.setName("test");
        user.setEmail("test@qq.com");
        mongoTemplate.insert(user);
        System.out.println(user);
    }

    //查询所有
    @Test
    public void testFindUser() {
        List<User> userList = mongoTemplate.findAll(User.class);
        System.out.println(userList);
    }

    //根据id查询
    @Test
    public void testFindUserById(){
        User user = mongoTemplate.findById("6412f9b27f3f675ef4c5ebb6", User.class);
        System.out.println(user);
    }
    //修改
    @Test
    public void testUpdateUser() {
        Criteria criteria = Criteria.where("_id").is("6412f9b27f3f675ef4c5ebb6");
        Query query = new Query(criteria);
        Update update = new Update();
        update.set("name", "zhangsan");
        update.set("age", 99);
        UpdateResult result = mongoTemplate.upsert(query, update, User.class);//改一条
        //UpdateResult result = mongoTemplate.updateMulti(query, update, User.class);//改多条
        long count = result.getModifiedCount();
        System.out.println(count);
    }

    //删除
    @Test
    public void testRemove() {
        Criteria criteria = Criteria.where("_id").is("6412f9b27f3f675ef4c5ebb6");
        Query query = new Query(criteria);
        DeleteResult result = mongoTemplate.remove(query, User.class);
        long count = result.getDeletedCount();
        System.out.println(count);
    }

    //条件查询 and
    @Test
    public void findUserList() {

        Criteria criteria = Criteria.where("name").is("test").and("age").is(20);
        Query query = new Query(criteria);

        List<User> userList = mongoTemplate.find(query, User.class);
        System.out.println(userList);
    }


    //模糊查询
    @Test
    public void findUsersLikeName() {

        Pattern pattern = Pattern.compile("^zhang", Pattern.CASE_INSENSITIVE);
        Criteria criteria = Criteria.where("name").regex(pattern);
        Query query = new Query(criteria);
        List<User> userList = mongoTemplate.find(query, User.class);
        System.out.println(userList);
    }

    //分页查询
    @Test
    public void findUsersPage() {
        Query query = new Query();
        //先查询总记录数
        long count = mongoTemplate.count(query, User.class);
        System.out.println(count);
        //后查询分页列表
        List<User> userList = mongoTemplate.find(query.skip(0).limit(2), User.class);
        System.out.println(userList);
    }
}

源码:https://gitee.com/dengyaojava/guigu-syt-parent

posted @ 2023-06-12 19:17  自律即自由-  阅读(186)  评论(0编辑  收藏  举报