1、MongoDB简介
MongoDB 是一个开源的、高性能、无模式(schema-free)的文档型数据库,它属于 NoSQL 数据库的一种。MongoDB 的设计初衷是为了简化开发和方便扩展,同时提供可扩展的高性能数据存储解决方案。
以下是 MongoDB 的一些关键特点:
- 面向文档:MongoDB 中的数据以文档的形式存储,这些文档是键值对的集合,类似于 JSON 对象但使用的是 BSON(Binary JSON)格式,这使得它可以存储复杂的数据类型。
- 无模式(Schema-less):与关系型数据库不同,MongoDB 不需要预先定义固定的表结构,每个文档可以有不同的字段和数据类型。
- 高可用性和扩展性:MongoDB 支持自动分片(sharding),这有助于水平扩展,能够处理大量的数据和高并发访问。
- 丰富的查询语言:MongoDB 提供了强大的查询能力,其语法接近于面向对象的查询语言,支持复杂的查询操作,包括排序、聚合等。
- 索引支持:为了加快查询速度,MongoDB 支持对字段创建索引,包括单字段索引、复合索引、地理空间索引等。
- 复制和容错:通过副本集(replica set),MongoDB 可以实现数据的冗余存储,提高系统的可靠性和容错能力。
- 易于使用和集成:MongoDB 提供了多种编程语言的驱动程序,方便开发者进行应用开发,并且拥有图形化管理工具如 Compass、Navicat、Studio 3T等来辅助数据库管理和维护。
- 社区和支持:作为一个广泛使用的数据库系统,MongoDB 拥有一个活跃的社区和官方提供的商业支持服务。
MongoDB 被设计用来满足现代应用程序的需求,特别是那些需要处理大量非结构化或半结构化数据的应用场景,比如内容管理系统、实时分析、移动应用后端等。由于其灵活性和性能优势,MongoDB 成为许多开发者和企业的首选数据库解决方案之一。
2、MongoDB安装
Linux安装
下载MongoDB Community Server
下载地址:https://www.mongodb.com/try/download/community
解压后启动MongoDB Server
1 2 3 4
| # 创建dbpath和logpath mkdir -p /mongodb/data /mongodb/log # 进入mongodb目录,启动mongodb服务 bin/mongod --port=27017 --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log
|
3、SpringBoot集成MongoDB
3.1、环境准备
1、引入依赖
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
|
完整依赖如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency> </dependencies>
|
2、配置
application.properties
1 2 3 4 5 6 7 8 9 10 11 12
| spring.data.mongodb.host = 127.0.0.1 spring.data.mongodb.port = 27017 spring.data.mongodb.database = test spring.data.mongodb.auto-index-creation = true
logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG logging.level.org.mongodb.driver.connection=DEBUG
|
连接配置可参考文档 https://www.mongodb.com/zh-cn/docs/manual/reference/connection-string/
3.2、文档操作
1、新增实体
1 2 3 4 5 6 7 8 9 10 11
| @Data @AllArgsConstructor @NoArgsConstructor @Builder @Document(collection = "person") public class Person { @Id private Long id; private String name; private Integer age; }
|
2、添加集合文档
集合操作时注入MongoTemplate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @SpringBootTest(classes = MongoApplication.class) @RunWith(SpringRunner.class) public class InsertTests { @Resource private MongoTemplate mongoTemplate;
@Test public void testInsert() { Person person = Person.builder().id(2L).name("river").age(18).build(); mongoTemplate.insert(person);
mongoTemplate.save(Person.builder().id(2L).name("zhangsan").age(28).build());
List<Person> persons = new ArrayList<>(); for (int i = 100; i <= 150; i++) { person = Person.builder().id(Long.valueOf(i)).name("lisi" + i).age(i).build(); persons.add(person); } mongoTemplate.insertAll(persons); } }
|
插入数据时: insert插入的_id 不能有重复,否则会报 DuplicateKeyException 提示主键重复; save对已存在的数据进行更新;
批处理操作时: insertAll可以一次性插入所有数据,效率较高;save需遍历所有数据,一次插入或更新,效率较低。
3、查询集合文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| @Slf4j @SpringBootTest(classes = MongoApplication.class) @RunWith(SpringRunner.class) public class QueryTests { @Autowired private MongoTemplate mongoTemplate;
@Test public void find() { List<Person> personList = mongoTemplate.findAll(Person.class); log.info("查询结果:{}", personList);
Person byId = mongoTemplate.findById(1L, Person.class); log.info("查询结果:{}", byId.toString());
Query query = new Query(Criteria.where("name").is("river")); Person result = mongoTemplate.findOne(query, Person.class); log.info("查询结果:{}", result);
query = new Query(Criteria.where("age").gt(18)); List<Person> list = mongoTemplate.find(query, Person.class); log.info("查询结果:{}", list);
Criteria criteria = Criteria.where("age").gt(18).lte(30); query = new Query(criteria); list = mongoTemplate.find(query, Person.class); log.info("查询结果:{}", list);
Criteria name = Criteria.where("name").is("zhangsan"); Criteria age = Criteria.where("age").is(18); criteria = new Criteria().andOperator(name, age); query = new Query(criteria); list = mongoTemplate.find(query, Person.class); log.info("查询结果:{}", list);
query = new Query(Criteria.where("age").is("20")) .with(Sort.by("id")) .limit(3).skip(5); list = mongoTemplate.find(query, Person.class); log.info("查询结果:{}", list); } }
|
Criteria是标准查询的接口,可以引用静态的Criteria.where的把多个条件组合在一起,就可以轻松地将多个方法查询连接起来,方便我们操作查询语句。
4、更新集合文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| @Slf4j @SpringBootTest(classes = MongoApplication.class) @RunWith(SpringRunner.class) public class UpdateTests { @Autowired private MongoTemplate mongoTemplate;
@Test public void update() { Person person = mongoTemplate.findById(1L, Person.class); person.setName("wangwu"); mongoTemplate.save(person);
Query query = new Query(Criteria.where("id").is(1L)); Update update = new Update().set("name", "lisi"); UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Person.class);
log.info("updateResult: {}", updateResult.getModifiedCount());
} }
|
如果更新后的结果和更新前的结果是相同,返回0。
updateFirst() 只更新满足条件的第一条记录
updateMulti() 更新所有满足条件的记录
upsert() 没有符合条件的记录则插入数据
5、删除集合文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Slf4j @SpringBootTest(classes = MongoApplication.class) @RunWith(SpringRunner.class) public class DeleteTests { @Autowired private MongoTemplate mongoTemplate;
@Test public void delete() { Query query = new Query(Criteria.where("id").is(1L)); DeleteResult remove = mongoTemplate.remove(query, Person.class); log.info("删除的条数为:{}", remove.getDeletedCount());
query = new Query(Criteria.where("id").is(2L)); Person per = mongoTemplate.findAndRemove(query, Person.class); log.info("删除的文档: {}", per); } }
|
3.3、去掉_class属性
使用MongoTemplate写入文档时,会自动将_class属性添加到文档中,一般不需要使用_class属性,可以配置去掉_class属性。
1 2 3 4 5 6 7 8 9 10 11 12
| @Configuration public class MongoConfig {
@Bean("mongoTemplate") public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext mongoMappingContext) { DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory); MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext); mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); return new MongoTemplate(mongoDbFactory, mappingMongoConverter); } }
|
3.4、忽略字段
忽略字段,即不将字段写入到数据库中,可以通过注解@Transient实现。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Data @AllArgsConstructor @NoArgsConstructor @Builder @Document(collection = "person") public class Person { @Id private Long id; private String name;
@Transient private Integer age; }
|