首先我们先说一下,我们遇到的坑全都是在设置用户名和密码的情况下才发生的,如果不设置MongoDB用户名和密码和密码的话,可以很轻松的成功整合。

bug1

我们打开Linux操作系统MongoDB对应端口号的防火墙,以及在腾讯云服务器安全组开放对应端口号

bug2

不要加这个东西:

@SpringBootApplication(exclude = MongoAutoConfiguration.class)

网上有很多教程叫我们加这个东西,但是我们不能加这个东西,因为SpringBoot可以给我们自动装配MongodbTemplate,如果我们加上这个注解的话SpringBoot就不会给我们自动注入了,我们就需要手动添加MongodbTemplate,其中我们为了手动配置,还需要引入

spring-data-mongodb

这个jar包。

代码如下:

@Configuration
public class AppConfig {
	@Bean
	public MongoClient mongoClient() {
	    return MongoClients.create("mongodb://101.43.166.179:27017");
	}
	@Bean
	public MongoTemplate mongoTemplate() {
	    return new MongoTemplate(mongoClient(), "mydatabase");
	}
}

如果我们不添加用户的用户名和密码的话,我们这个就可以成功了。

但是如果我们要添加用户名和密码的话,这个就会直接报错:用户没有权限。

为什么呢?原因是当我们使用这个手动注入的时候,我们的application.yml里面配置的账号和密码就会被SpringBoot自动省略。相当于SpringBoot只看你上面代码的配置,它会认为你没有设置账号和密码。

因此我们还是要让SpringBoot自动注入,然后读取application.yml里面的配置文件信息

 bug3

用户权限问题:

我们先来看我们的yml配置

spring:
  data:
    mongodb:
      uri: mongodb://用户名:密码@101.43.166.179:27017/mydb?authSource=admin&authMechanism=SCRAM-SHA-1

 也许你会很疑问,为什么用户名:密码是写在URL路径里面的,实际上是因为我们的monodb每一个数据库都会有各自的权限,我一个URL对应一个数据库,也就对应着这个数据库的相应的权限,因此这里需要写上这个数据的用户名和密码。

咦?奇怪了,我没有对这个数据库设定用户和密码呀,那我就不写前面的用户名和密码了,于是,就直接报错了,报错理由是你没有权限,因为你的admin设置账号和密码了,那么使用其他的数据库的时候,如果它们没有单独设置用户名和密码的时候就需要admin的账号和密码。

因此我们在后面加上了这一段:

authSource=admin&authMechanism=SCRAM-SHA-1

代表我的权限来源是admin,这样就可以成功登录了。

  • mongodb的每一个数据库都可以有对应的账号和密码。URL里面的 用户名:密码是指我这个数据库的用户和密码。如果你设置了用户和密码,就不需要写authSource=admin&authMechanism=SCRAM-SHA-1,因为我不需要指名URL前面写的是admin的用户名和密码。如果你没有设置用户名和密码,那么就需要用到admin的账号和密码才可以使用,这个时候你的前面写的是admin的用户和密码,然后后面就需要加上authSource=admin。
  • 你把这些分开写也可以,没有必要全部写在一个URL里面,这个看个人喜好
  • URL后面放的数据库名我们不需要提前的mongodb里面创建(use 数据库名),因为系统会自动的帮我们创建这个数据库,并且建表。根本原因是我们的mongodb使用 use 数据库名 有使用这个数据库和创建这个数据库两个功能,所以不需要你直接创建,系统会默认我use一个数据库。但是我如果没有提前创建数据库的话,那么就必须加上authSource=admin&authMechanism=SCRAM-SHA-1,因为我没有提前设置这个数据库的账号和密码,只能用admin的去登录使用

 整体步骤过一遍

安装

拉取docker镜像 

docker pull mongo:4.4

创建mongo数据持久化目录

mkdir -p /docker_volume/mongodb/data

运行容器

docker run -itd --name mongo -v /docker_volume/mongodb/data:/data/db -p 27017:27017 mongo:4.4 --auth
// 这里加上auth代表我们需要用户名密码登录
  • -v: 将宿主机的/docker_volume/mongodb/data映射到容器的/data/db目录,将数据持久化到宿主机,以防止删除容器后,容器内的数据丢失
  • –auth:需要密码才能访问容器服务

创建用户

登录mongo容器,并进入到【admin】数据库

docker exec -it mongo mongo admin

 创建一个用户,mongo 默认没有用户

db.createUser({ user:'root',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},'readWriteAnyDatabase']});

【user:‘root’ 】:设置用户名为root
【pwd:‘123456’】:设置密码为123456
【role:‘userAdminAnyDatabase’】:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
【db: ‘admin’】:可操作的数据库
【‘readWriteAnyDatabase’】:赋予用户读写权限

 我们可以给其他用户也设定用户名和密码

use admin
db.auth("root", "123456") //登录验证root账号
use test //进入要创建或修改用户的库
db.grantRolesToUser("test", [{role:"readWrite",db:"test"},{role:"dbAdmin", db:"test"}]) //修改用户权限
db.createUser({user:"sakura",pwd:"123456",roles:[{role:"dbAdmin", db:"sakura"},{role:"readWrite",db:"sakura"}]}) //创建用户

这样我们进入某一个数据库输入用户和密码之后就可以进行正常的操作了。

注意,我们可以建立admin,然后所有的数据库共享admin的用户名和密码,但实际上admin和其他数据库没有主从关系,只是起名为admin而已,我如果某一个数据有自己的账号和密码的话,不需要进入之后先登录admin,再登录其他的东西,直接use之后登录就好。

SpringBoot整合MongoDB

导入pom文件

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.11</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

写yml文件

spring:
  data:
    mongodb:
      uri: mongodb://root:123456@101.43.166.179:27017/hhh?authSource=admin&authMechanism=SCRAM-SHA-1

写实体类

@Document("mydb")
public class User {

    @Id
    @Field("_id")
    private Integer id;

    private String username;

    private String password;

    public User(Integer id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
}
  • 这里的@Document("mydb")是表的映射,我们会在我们的数据库里面建立mydb这一张表
  • 如果不加这个注解的话,系统就会以这个类的名字作为表明添加表

@Field("_id")是id与表中数据的映射,如果我们不设置这个主键的话,那么mongodb会给我们自动设置一个叫_id的主键,但是我们推荐自己设置主键,所以我们加上@Id,然后把我们的这个id与系统的_id做一个对应。 

实际上,@Id和@Field("_id")可以达到一样的效果,我们写一个就行,但是最好都写上,其实我们就算不写,系统也会给我们默认用一个适合的字段作为主键。

可以发现我们的效果很成功!!!