MongoDB第一话 -- Docker安装MongoDB以及Springboot集成MongoDB

本文主要记录MongoDB的安装及使用

1.MongoDB介绍

MongoDB是一个基于分布式文件存储的数据库,是非关系型数据库,是面向集合存储。易使用,易部署,存储非常方便。
因为是面向集合存储,结构完全自定义,不需要维护关系,可以通过字段来检索。

2.docker安装MongoDB

基于liunx centos7,docker-compsoe,镜像mongo.4.2.21

2.1 docker-compose.yaml文件

version: '3.7'
services:
  mongo01:
    image: mongo:5.0
    container_name: mongo01
    # ports:
    #- "27017:27017"
    environment:
    - TZ=Asia/Shanghai
    #不带代表无密码
    - MONGO_INITDB_ROOT_USERNAME=root
    - MONGO_INITDB_ROOT_PASSWORD=mongodb@tt
    volumes:
    - ./db:/data/db
    networks:
    - my-net
  #不想装客户端时 可以用web端控制台 
  mongo-console:
    image: mongo-express
    container_name: mongo-console
    ports:
    - "8081:8081"
    environment:
    - ME_CONFIG_MONGODB_SERVER=mongo01
    #管理控制台需要密码可以这么设置
#    - ME_CONFIG_BASICAUTH_USERNAME=admin
#    - ME_CONFIG_BASICAUTH_PASSWORD=admin
    - TZ=Asia/Shanghai
    networks:
    - my-net

networks:
  #新增的网络 内部服务名调用
  my-net:
    external: true

2.2 启动容器

[root@m mongo]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                      NAMES
67d4aa11d347        mongo:5.0        "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:27017->27017/tcp   mongo01
df4476c00447        mongo-express       "tini -- /docker-ent…"   About a minute ago   Up About a minute   0.0.0.0:8081->8081/tcp     mongo-console

2.3 控制台界面

访问ip:8081进入控制台,数据忽略
在这里插入图片描述

2.4 密码相关

默认启动的MongoDB是没有密码的,如果想设置密码还需要再启动后进行如下操作.

  • 进入docker容器内交互模式,然后执行mongo指令进入到MongoDB的连接状态
 docker exec -it mongo01 /bin/bash
 mongo
  • 创建一个admin用户,并赋予userAdminAnyDatabase这个权限和admin这个库
#创建admin用户
user admin
db.createUser({
	user:"admin",
	pwd:"password",
	role:[{role:"userAdminAnyDatabase",db:"admin"}]
})
  • 如果配置完成鉴权不生效,则需要修改/etc/mongo.conf配置文件,开启连接鉴权
#可以选择复制出来做映射 也可以执行下面命令 安装vim
#更新源
apt-get update
#安装 vim
apt-get install vim
#修改 mongo 配置文件
vim /etc/mongod.conf.orig

在这里插入图片描述

bindIp: 127.0.0.1 注释掉
#权限打开
security:
	authorization: enabled

然后再次重启容器即可,如果需要删除容器就建议使用映射配置文件的方式.

3.springboot集成MongoDB

基于springboot2.6.8

3.1 pom依赖

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

3.2 yml配置

spring:
  data:
    mongodb:
      #有密码连接 账号密码包含特殊字符的需要用URLEncoder编码 库名必填
      #uri: mongodb://admin:123456@192.168.0.221:27017/imgdb
      #集群方式
      #uri: mongodb://192.168.0.221:27017,192.168.0.221:27018/imgdb
      uri: mongodb://192.168.0.221:27017/imgdb
      repositories:
        type: none
  servlet:
  	#spring文件上传大小限制 默认1MB
    multipart:
      max-file-size: 1024MB
      max-request-size: 1024MB

3.3 基于集合方式的存储

和mysql一样,只不过不支持关联关系

  • 首先准备一个实体类,玩过JPA的肯定不陌生
@Data
@Document("student")
public class Student {

    /**
     * 若不加 插入数据数会默认生成 ObjectId 类型的_id 字段
     */
//    @Id
//	Long id;

    Long uid;
    String username;
    Integer age;
    Date createTime;
}
  • 插入代码
Student student = new Student();
student.setUid(new Date().getTime());
student.setUsername("张三");
student.setAge(19);
student.setCreateTime(new Date());

Student insert = mongoTemplate.insert(student);
log.info("插入数据成功:{}", insert);
  • 查询代码
List<Student> students = mongoTemplate.findAll(Student.class);

Student byId = mongoTemplate.findById("62ba9d1122a67e0c281b74f1", Student.class);

//存在多条会默认去最早的一条
Student one = mongoTemplate.findOne(
        Query.query(Criteria.where("username").is("张三")), Student.class);
log.info(JSONObject.toJSONString(one));
  • 更新和删除代码
Update update = new Update();
update.set("username", "李四");
update.set("age", 29);
UpdateResult upsert = mongoTemplate.upsert(Query.query(Criteria.where("_id").is("62ba9d1122a67e0c281b74f1")), update, Student.class);
log.info("更新条数:{}", upsert.getModifiedCount());

//删除
mongoTemplate.remove(Query.query(Criteria.where("_id").is("62ba9d87ac96c15a68abdead")), Student.class);

3.4 存储集合图

在这里插入图片描述

4.基于MongoDB实现文件存储系统

如果使用上面实体类的方式存储文件,最大只支持16M,所以直接采用GridFs
GridFsTemplate:上传成功后会自动生成两个集合,fs.files集合存储文件信息,fs.chunks存储文件元数据。

4.1 文件上传

@RequestMapping("/upload")
public String upload(@RequestParam(value = "img") MultipartFile file) {
    try {

        InputStream inputStream = file.getInputStream();
        String originalFilename = file.getOriginalFilename();
        String contentType = file.getContentType();
        //重命名 偷懒的操作
        String fileName = new Date().getTime() + "." + contentType.split("/")[1];

        //mongo限制Document最大为16MB 大文件的需要用gridFs
        //GridFS使用两个集合来存储文件。fs.files集合存储文件信息,fs.chunks存储文件元数据。
        Map<String, Object> map = new HashMap<>();
        map.put("originName", originalFilename);
        map.put("originSize", file.getSize());

        ObjectId store = gridFsTemplate.store(inputStream, fileName, contentType, new Document(map));
        log.info("上传文件成功:{},{},{}", originalFilename, fileName, store.toString());
	return fileName;
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("文件上传失败");
    }
}

4.2 图片预览代码

没有什么业务用暂时只实现图片

@GetMapping(value = "/preview/{filename}")
public void preview(@PathVariable String filename, HttpServletResponse response) throws Exception {
    GridFSFile fsFile = gridFsTemplate.findOne(Query.query(Criteria.where("filename").is(filename)));
    if (fsFile != null) {
        GridFSDownloadStream downloadStream = GridFSBuckets.create(mongoTemplate.getDb()).openDownloadStream(fsFile.getObjectId());
        GridFsResource resource = new GridFsResource(fsFile, downloadStream);

        //超过一定大小的文件 会直接下载
        response.setContentType(fsFile.getMetadata().getString("_contentType"));

        ServletOutputStream os = response.getOutputStream();
        InputStream is = resource.getInputStream();

        IOUtils.copy(is, os);
        os.close();
        is.close();
    }
}

4.3 图片和视频预览图

在这里插入图片描述

在这里插入图片描述

4.4 文件下载

@GetMapping(value = "/down/{filename}")
public void downImg(@PathVariable String filename, HttpServletResponse response) throws Exception {

    GridFSFile fsFile = gridFsTemplate.findOne(Query.query(Criteria.where("filename").is(filename)));
    if (fsFile != null) {
        GridFSDownloadStream downloadStream = GridFSBuckets.create(mongoTemplate.getDb()).openDownloadStream(fsFile.getObjectId());
        GridFsResource resource = new GridFsResource(fsFile, downloadStream);

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fsFile.getFilename() + "\"");

        ServletOutputStream os = response.getOutputStream();
        InputStream is = resource.getInputStream();

        IOUtils.copy(is, os);
        os.close();
        is.close();
    }
}

特别注意的一点哈:response.setxx切记放在写流前面,不然不会生效

以上就是本章的全部内容了。

上一篇:MQTT第二话 – emqx高可用集群实现
下一篇:MongoDB第二话 – MongoDB高可用集群实现

书卷多情似故人,晨昏忧乐每相亲

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值