SpringBoot集成MongoDB

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: MongoDB是一个基于分布式文件存储的数据库,c++编写,可扩展高性能数据存储方案。MongoDb介于关系型数据库和非关系型数据库之间,是非关系型数据库中功能最多的,最像关系型数据库。数据结构非常松散可以存储非常复杂的数据对象。Mongodb支持的查询语言非常强大,语法类似于面向对象的查询语言,几乎可以实现类似关系型数据库单表查询的所有功能,而且还支持对数据建立索引。

[toc]

NoSql

NotOnly Sql,不仅仅是 sql 。

NoSql数据库分类:
键值对:redis
列存储:Hbase
文档型:mongodb
图形(graph)数据库:Neo4j,infogrid

MongoDB

是一个基于分布式文件存储的数据库,c++编写,可扩展高性能数据存储方案。MongoDb介于关系型数据库和非关系型数据库之间,是非关系型数据库中功能最多的,最像关系型数据库。数据结构非常松散可以存储非常复杂的数据对象。Mongodb支持的查询语言非常强大,语法类似于面向对象的查询语言,几乎可以实现类似关系型数据库单表查询的所有功能,而且还支持对数据建立索引。

在高负载的情况下,MongoDB 天然支持水平扩展和高可用,可以很方便地添加节点/实例,以保证服务性能和可用性。MongoDB 可以用于代替传统的关系型数据库或键/值存储方式,皆在为 Web 应用提供可扩展的高可用高性能数据存储解决方案。

存储结构

  • 文档(Document) :MongoDB 中最基本的单元,由 BSON 键值对(key-value)组成

  • 集合(Collection) :一个集合可以包含多个文档,每个文档的结构可以不同

  • 数据库(Database) :一个数据库中可以包含多个集合,可以在 MongoDB 中创建多个数据库

BSON是 Binary JSON的简称,是 JSON 文档的二进制表示,支持将文档和数组嵌入到其他文档和数组中,还包含允许表示不属于 JSON 规范的数据类型的扩展。与 JSON 相比,BSON 着眼于提高存储和扫描效率

传统关系型数据和MongoDB类比:

MongoDB 传统关系型数据库
Database schema
Collection Table
Document Row
Field Column

特性

  • BSON:MongoDB 中的数据就是一个 BSON 文档,它是由键值对组成的数据结构,类似于 JSON 对象,是 MongoDB 中的基本数据单元
  • 模式自由:集合的概念类似 MySQL 里的表,但它不需要定义任何模式,能够用更少的数据对象表现复杂的领域模型对象
  • 支持多种查询方式 :MongoDB 查询 API 支持读写操作 (CRUD)以及数据聚合、文本搜索和地理空间查询。
  • 支持 ACID 事务 :NoSQL 数据库通常不支持事务,为了可扩展和高性能进行了权衡。不过,也有例外,MongoDB 就支持事务。与关系型数据库一样,MongoDB 事务同样具有 ACID 特性。MongoDB 单文档原生支持原子性,也具备事务的特性。MongoDB 4.0 加入了对多文档事务的支持,但只支持复制集部署模式下的事务,也就是说事务的作用域限制为一个副本集内。MongoDB 4.2 引入了分布式事务,增加了对分片集群上多文档事务的支持,并合并了对副本集上多文档事务的现有支持。
  • 聚合管道:聚合管道用来执行数据聚合、过滤的操作
  • 支持多种类型的索引 :单字段索引、复合索引、多键索引、哈希索引、文本索引、 地理位置索引等
  • 支持 failover :提供自动故障恢复的功能,主节点发生故障时,自动从从节点中选举出一个新的主节点,确保集群的正常使用,这对于客户端来说是无感知的
  • 支持分片集群 :MongoDB 支持集群自动切分数据,让集群存储更多的数据,具备更强的性能。在数据插入和更新时,能够自动路由和存储。
  • 支持存储大文件 :MongoDB 的单文档存储空间要求不超过 16MB。对于超过 16MB 的大文件,MongoDB 提供了 GridFS 来进行存储,通过 GridFS,可以将大型数据进行分块处理,然后将这些切分后的小文档保存在数据库中。

实践

pom


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

yml


spring:
  application:
    name: MongoApp
  data:
    mongodb:
      uri: mongodb://127.0.0.1:27017/FirstMongoDBSchema



logging:
  level:
    org.springframework.data.mongodb: debug

model


package com.ramble.mongodb.model;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
import java.util.Date;

@Data
@Document(collection = "students")
public class Student implements Serializable {
   
   

    @Id
    private Long id;
    private String userName;
    private String passWord;
    private Integer age;
    private Date createTime;
}
  • Document:此实体对应的文档
  • collection="students":此实体所属的集合为students集合
  • Id:文档的id,唯一标识

repository


package com.ramble.mongodb.repository;
import com.ramble.mongodb.model.Student;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudentRepository extends MongoRepository<Student, Integer> {
   
   

List<Student> findByUserName(String userName);

List<Student> findByPassWordLike(String passWord);

@Query(   value = "{'age' : {\"$gt\" : ?0}}")List<Student> findList(Integer age);

}
  • MongoRepository:继承MongoRepository即可开箱即用基本的CURD操作
  • Query: 如果默认的无法满足需求,可以编写自定义查询语句
  • findList:表示查询age 大于 传递进来的age参数的数据,?0 表示获取参数列表的第一个参数,这里就体现框架的强大之处了,这里的写法非常类似 spring-data-jpa 的写法。框架屏蔽了技术实现的细节,用过jpa的开发人员可以很平滑的在项目中继承mongodb。
  • findByUserName: 查询userName等于传递进来的userName参数的数据,会自动生成查询语句,可通过控制台输出观察到

controller



package com.ramble.mongodb.controller;
import com.alibaba.fastjson.JSON;
import com.ramble.mongodb.model.Student;
import com.ramble.mongodb.repository.StudentRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;

@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/student")
public class StudentController {
   
   

    private StudentRepository studentRepository;

    @PostMapping("/")
    public void create(@RequestBody Student param) {
   
   
        Student save = studentRepository.save(param);
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable Integer id) {
   
   
        studentRepository.deleteById(id);
    }

    @PutMapping("/")
    public Student update(@RequestBody Student param) {
   
   
        Student save = studentRepository.save(param);
        return save;
    }

    @GetMapping("/{id}")
    public Student get(@PathVariable Integer id) {
   
   
        Optional<Student> byId = studentRepository.findById(id);
        return byId.get();
    }

    @GetMapping("/")
    public List<Student> find() {
   
   
        List<Student> all = studentRepository.findAll();
        return all;
    }

    @GetMapping("/biz")
    public void findBiz() {
   
   
        List<Student> c = studentRepository.findByUserName("string");
        log.info("查询结果为:" + JSON.toJSONString(c));
        List<Student> like = studentRepository.findByPassWordLike("123");
        log.info("查询结果为:" + JSON.toJSONString(like));
        List<Student> list = studentRepository.findList(9);
        log.info("查询结果为:" + JSON.toJSONString(list));
    }


}

findBiz 接口打印的日志为:



2023-07-18 14:21:46.105 DEBUG 29044 --- [nio-8080-exec-3] o.s.d.m.r.query.MongoQueryCreator        : Created query Query: { "userName" : "string"}, Fields: {}, Sort: {}
2023-07-18 14:21:46.106 DEBUG 29044 --- [nio-8080-exec-3] o.s.data.mongodb.core.MongoTemplate      : find using query: { "userName" : "string"} fields: Document{
  
  {}} for class: class com.ramble.mongodb.model.Student in collection: students
2023-07-18 14:21:46.110  INFO 29044 --- [nio-8080-exec-3] c.r.m.controller.StudentController       : 查询结果为:[{"age":0,"createTime":1689657852733,"id":222,"passWord":"string","userName":"string"},{"age":0,"createTime":1689657852733,"id":333,"passWord":"string","userName":"string"}]
2023-07-18 14:21:46.111 DEBUG 29044 --- [nio-8080-exec-3] o.s.d.m.r.query.MongoQueryCreator        : Created query Query: { "passWord" : { "$regularExpression" : { "pattern" : "123", "options" : ""}}}, Fields: {}, Sort: {}
2023-07-18 14:21:46.112 DEBUG 29044 --- [nio-8080-exec-3] o.s.data.mongodb.core.MongoTemplate      : find using query: { "passWord" : { "$regularExpression" : { "pattern" : "123", "options" : ""}}} fields: Document{
  
  {}} for class: class com.ramble.mongodb.model.Student in collection: students
2023-07-18 14:21:46.114  INFO 29044 --- [nio-8080-exec-3] c.r.m.controller.StudentController       : 查询结果为:[{"age":20,"createTime":1689659233455,"id":202,"passWord":"123456","userName":"cr8"}]
2023-07-18 14:21:46.115 DEBUG 29044 --- [nio-8080-exec-3] o.s.d.m.r.query.StringBasedMongoQuery    : Created query Document{
  
  {age=Document{
  
  {$gt=9}}}} for Document{
  
  {}} fields.
2023-07-18 14:21:46.115 DEBUG 29044 --- [nio-8080-exec-3] o.s.data.mongodb.core.MongoTemplate      : find using query: { "age" : { "$gt" : 9}} fields: Document{
  
  {}} for class: class com.ramble.mongodb.model.Student in collection: students
2023-07-18 14:21:46.117  INFO 29044 --- [nio-8080-exec-3] c.r.m.controller.StudentController       : 查询结果为:[{"age":100,"createTime":1689659233455,"id":22,"passWord":"string","userName":"c8"},{"age":20,"createTime":1689659233455,"id":232,"passWord":"string","userName":"cr8"},{"age":20,"createTime":1689659233455,"id":202,"passWord":"123456","userName":"cr8"}]

通过log可以观察到 MongoRepository 自动生成的查询语句以及 Query 方法生成的查询语句

MongoTemplate

除了 MongoRepository ,MongoTemplate 也可以用来访问 mongodb ,这种方式更加原始,需要开发人员编写的代码更多,但同时它的可自定义程度更高,可以用来编写复杂的查询语句。



package com.ramble.mongodb.repository;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.ramble.mongodb.model.FirstMongoDBSchemeCollection;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.List;

@Repository
public class FirstMongoDBSchemeCollectionRepositoryImpl implements FirstMongoDBSchemeCollectionRepository {
   
   

    @Resource
    private MongoTemplate mongoTemplate;

    public void insert(FirstMongoDBSchemeCollection model) {
   
   
        FirstMongoDBSchemeCollection insertResult = mongoTemplate.insert(model);
    }

    @Override
    public void save(FirstMongoDBSchemeCollection model) {
   
   
        FirstMongoDBSchemeCollection saveResult = mongoTemplate.save(model);
    }

    @Override
    public void remove(FirstMongoDBSchemeCollection model) {
   
   
        DeleteResult deleteResult = mongoTemplate.remove(model);
        //mongoTemplate.remove
    }

    @Override
    public void update(FirstMongoDBSchemeCollection model) {
   
   
        Query query = new Query(Criteria.where("id").is(model.getId()));
        Update update = new Update();
        update.set("name", model.getName());
        update.set("age", model.getAge());
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, FirstMongoDBSchemeCollection.class);
    }

    @Override
    public FirstMongoDBSchemeCollection findById(String id) {
   
   
        Query query = new Query(Criteria.where("id").is(id));
        FirstMongoDBSchemeCollection model = mongoTemplate.findById(id, FirstMongoDBSchemeCollection.class);
        return model;
    }

    @Override
    public FirstMongoDBSchemeCollection findOne(FirstMongoDBSchemeCollection model) {
   
   
        Query query = new Query();
        FirstMongoDBSchemeCollection findResult = mongoTemplate.findOne(query, FirstMongoDBSchemeCollection.class);
        return findResult;
    }

    @Override
    public List<FirstMongoDBSchemeCollection> findList() {
   
   
        Query query = new Query();
        List<FirstMongoDBSchemeCollection> firstMongoDBSchemeCollections = mongoTemplate.find(query, FirstMongoDBSchemeCollection.class);
        return firstMongoDBSchemeCollections;
    }
}

引用

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
5天前
|
前端开发 Java 应用服务中间件
从零手写实现 tomcat-08-tomcat 如何与 springboot 集成?
该文是一系列关于从零开始手写实现 Apache Tomcat 的教程概述。作者希望通过亲自动手实践理解 Tomcat 的核心机制。文章讨论了 Spring Boot 如何实现直接通过 `main` 方法启动,Spring 与 Tomcat 容器的集成方式,以及两者生命周期的同步原理。文中还提出了实现 Tomcat 的启发,强调在设计启动流程时确保资源的正确加载和初始化。最后提到了一个名为 mini-cat(嗅虎)的简易 Tomcat 实现项目,开源于 [GitHub](https://github.com/houbb/minicat)。
|
24天前
|
消息中间件 Java Kafka
Springboot集成高低版本kafka
Springboot集成高低版本kafka
|
1月前
|
NoSQL Java Redis
SpringBoot集成Redis解决表单重复提交接口幂等(亲测可用)
SpringBoot集成Redis解决表单重复提交接口幂等(亲测可用)
355 0
|
2月前
|
NoSQL Java Redis
SpringBoot集成Redis
SpringBoot集成Redis
464 0
|
2月前
|
NoSQL Java Redis
小白版的springboot中集成mqtt服务(超级无敌详细),实现不了掐我头!!!
小白版的springboot中集成mqtt服务(超级无敌详细),实现不了掐我头!!!
296 1
|
1月前
|
存储 JSON Java
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
29 2
|
6天前
|
前端开发 Java 应用服务中间件
从零手写实现 tomcat-08-tomcat 如何与 springboot 集成?
本文探讨了Spring Boot如何实现像普通Java程序一样通过main方法启动,关键在于Spring Boot的自动配置、内嵌Servlet容器(如Tomcat)以及`SpringApplication`类。Spring与Tomcat集成有两种方式:独立模式和嵌入式模式,两者通过Servlet规范、Spring MVC协同工作。Spring和Tomcat的生命周期同步涉及启动、运行和关闭阶段,通过事件和监听器实现。文章鼓励读者从实现Tomcat中学习资源管理和生命周期管理。此外,推荐了Netty权威指南系列文章,并提到了一个名为mini-cat的简易Tomcat实现项目。
|
2天前
|
缓存 NoSQL Java
springboot业务开发--springboot集成redis解决缓存雪崩穿透问题
该文介绍了缓存使用中可能出现的三个问题及解决方案:缓存穿透、缓存击穿和缓存雪崩。为防止缓存穿透,可校验请求数据并缓存空值;缓存击穿可采用限流、热点数据预加载或加锁策略;缓存雪崩则需避免同一时间大量缓存失效,可设置随机过期时间。文章还提及了Spring Boot中Redis缓存的配置,包括缓存null值、使用前缀和自定义过期时间,并提供了改造代码以实现缓存到期时间的个性化设置。
|
7天前
|
Java Docker 容器
SpringBoot项目集成XXL-job
SpringBoot项目集成XXL-job
|
9天前
|
Java 关系型数据库 数据库
【SpringBoot系列】微服务集成Flyway
【4月更文挑战第7天】SpringBoot微服务集成Flyway
【SpringBoot系列】微服务集成Flyway

相关产品

  • 云数据库 MongoDB 版