1. 概述

可能有一些胖友对 MongoDB 不是很了解,这里我们引用一段介绍:

FROM 《分布式文档存储数据库 MongoDB》

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

他支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。

Mongo 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

MongoDB 中的许多概念在 MySQL 中具有相近的类比。本表概述了每个系统中的一些常见概念。

对于不熟悉的胖友,可以先看下该表,然后开始本文的旅程。

MySQL MongoDB
库 Database 库 Database
表 Table 集合 Collection
行 Row 文档 Document
列 Column 字段 Field
joins 嵌入文档或者链接

在早期,在项目中 MongoDB 的 ORM 框架使用 Morphia 较多。随着 Spring Data MongoDB 的日趋完善,更为主流。目前,艿艿手头所有的项目,都从 Morphia 该用 Spring Data MongoDB 。

在 Spring Data MongoDB 中,有两种方式进行 MongoDB 操作:

  • Spring Data Repository 方式

  • MongoTemplate

艿艿:如果胖友还没安装 MongoDB ,可以参考下 《芋道 MongoDB 安装部署》 文章,先进行下安装。

2. 快速入门

示例代码对应仓库:lab-16-spring-data-mongodb 。

  • MongoDB 版本号:4.2.1

本小节,我们会使用 spring-boot-starter-data-mongodb 自动化配置 Spring Data MongoDB 主要配置。同时,使用 Spring Data Repository 实现的 MongoDB 的 CRUD 操作。

2.1 引入依赖

在 pom.xml 文件中,引入相关依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELEASE</version><relativePath/><!-- lookup parent from repository --></parent><modelVersion>4.0.0</modelVersion><artifactId>lab-16-spring-data-mongodb</artifactId><dependencies><!-- 自动化配置 Spring Data Mongodb --><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></dependencies></project>

具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

2.2 Application

创建 Application.java 类,配置 @SpringBootApplication 注解即可。代码如下:

// Application.java@SpringBootApplication(exclude = {ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class})
publicclass Application {
}

2.3 MongoDBConfig

在 cn.iocoder.springboot.lab16.springdatamongodb.config 包路径下,创建 MongoDBConfig 配置类。代码如下:

// MongoDBConfig.java@Configuration
publicclass MongoDBConfig {@Bean// 目的,就是为了移除 _class field 。参考博客 https://blog.csdn.net/bigtree_3721/article/details/82787411public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory,MongoMappingContext context,BeanFactory beanFactory) {// 创建 DbRefResolver 对象DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);// 创建 MappingMongoConverter 对象MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);// 设置 conversions 属性try {mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));} catch (NoSuchBeanDefinitionException ignore) {}// 设置 typeMapper 属性,从而移除 _class field 。mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));return mappingConverter;}}
  • 通过在自定义 MappingMongoConverter Bean 对象,避免实体保存到 MongoDB 中时,会多一个 _class 字段,存储实体的全类名。

2.4 配置文件

在 application.yml 中,添加 MongoDB 配置,如下:

spring:data:# MongoDB 配置项,对应 MongoProperties 类mongodb:host:127.0.0.1port:27017database:yourdatabaseusername:test01password:password01# 上述属性,也可以只配置 urilogging:level:org:springframework:data:mongodb:core:DEBUG# 打印 mongodb 操作的具体语句。生产环境下,不建议开启。

2.5 UserDO

在 cn.iocoder.springboot.lab16.springdatamongodb.dataobject 包路径下,创建 UserDO 类。代码如下:

@Document(collection = "User")
publicclass UserDO {/*** 用户信息*/publicstaticclass Profile {/*** 昵称*/private String nickname;/*** 性别*/private Integer gender;// ... 省略 setting/getting 方法}@Idprivate Integer id;/*** 账号*/private String username;/*** 密码*/private String password;/*** 创建时间*/private Date createTime;/*** 用户信息*/private Profile profile;// ... 省略 setting/getting 方法}
  • 在 UserDO 类中,我们内嵌了一个 profile 属性,它是 Profile 类。这里仅仅作为示例,实际场景下,还是建议把 User 和 Profile 拆分开。

  • 推荐阅读 《你应该知道的 MongoDB 最佳实践》 文章。对于初用 MongoDB 的开发者,往往错误的使用内嵌属性,需要去理解一下。

2.6 UserRepository

在 cn.iocoder.springboot.lab16.springdatamongodb.repository 包路径下,创建 UserRepository 接口。代码如下:

// ProductRepository.javapublicinterface UserRepository extends MongoRepository<UserDO, Integer> {
}