SpringBoot整合MongoDB

一、介绍

MongoDB是一个开源的文档数据库,采用分布式文件存储的方法,是NoSQL数据库中的一种。它的设计目标是为了在现代应用开发中解决传统关系型数据库所遇到的一些挑战,比如灵活性、可扩展性和性能等方面的问题。

以下是MongoDB的一些主要特点:

  1. 文档导向存储MongoDB采用文档导向的存储模式,数据以JSON格式存储,这种模式很适合应用程序的数据结构,可以更自然地映射到代码结构。

  2. 灵活的模式设计MongoDB不需要事先定义表结构,文档可以包含不同的字段,可以根据需要动态地添加或删除字段,因此更适合快速迭代和灵活的数据模型设计。

  3. 高性能MongoDB具有高性能的读写操作,支持在数据量较大的情况下进行高效的查询和写入操作,同时也支持基于索引的查询优化。

  4. 可扩展性MongoDB具有良好的横向扩展能力,可以通过添加更多的节点来扩展数据存储和处理能力,从而应对不断增长的数据量和访问压力。

  5. 复制和容错MongoDB支持数据的复制和容错机制,可以配置主从复制和分片集群,确保数据的可用性和可靠性。

  6. 丰富的功能和工具MongoDB提供了丰富的功能和工具,包括数据备份和恢复、数据加密、数据验证、文本搜索等功能,以及各种客户端驱动和管理工具。

总的来说,MongoDB是一个功能强大、灵活性高、性能优越的NoSQL数据库,适用于各种类型的应用程序,特别是那些需要处理大量数据和具有复杂数据结构的应用。

本文将介绍SpringBoot整合使用MongoDB,其服务的安装就不说了

二、代码

1)配置

1
2
3
4
5
6
7
8
spring:
data:
mongodb:
host: 主机地址
port: 端口
database: 数据库
authentication-database: admin
auto-index-creation: false

2)MongoRepository

可以使用MongoRepository来进行编码,这一点和MybatisPlus实体那块很像

1
2
3
4
5
6
7
8
9
package com.banmoon.repository;

import com.banmoon.entity.MemberAccountLogEntity;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MemberAccountLogRepository extends MongoRepository<MemberAccountLogEntity, Long> {
}

具体的实体MemberAccountLogEntity.java

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
package com.banmoon.entity;

import lombok.Data;
import lombok.experimental.FieldNameConstants;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.math.BigDecimal;

@Data
@FieldNameConstants
@Document(collection = "member_account_log")
public class MemberAccountLogEntity {

@Id
private Long id;

private String memberId;

private String memberName;

private BigDecimal totalConsumption;

private BigDecimal depositMoney;

}

使用MemberAccountLogRepository.java

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.banmoon.execute;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.banmoon.entity.MemberAccountLogEntity;
import com.banmoon.repository.MemberAccountLogRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
* 测试mongo的使用,使用MongoRepository
*/
@Slf4j
@Component
public class MongoExecute implements Runnable {

@Resource
private MemberAccountLogRepository memberAccountLogRepository;

@Override
public void run() {
insertOne();
insertBatch(50);
findAll();
update();
delete();
}

/**
* 删除
*/
private void delete() {
List<MemberAccountLogEntity> list = memberAccountLogRepository.findAll();
if (CollUtil.isNotEmpty(list)) {
memberAccountLogRepository.deleteById(list.get(0).getId());
}
}

/**
* 更新
*/
private void update() {
long id = 1729792683813355522L;
MemberAccountLogEntity entity = memberAccountLogRepository.findById(id)
.map(memberAccountLogEntity -> {
memberAccountLogEntity.setMemberName("半月无霜");
memberAccountLogEntity.setDepositMoney(new BigDecimal("1000"));
return memberAccountLogRepository.save(memberAccountLogEntity);
}).orElse(null);
log.info("修改后的信息,{}", memberAccountLogRepository.findById(id).get());
}

/**
* 查询所有
*/
private void findAll() {
List<MemberAccountLogEntity> list = memberAccountLogRepository.findAll();
log.info("mongoDB全部用户数量:{},详情:{}", list.size(), list);

// 添加条件,名字匹配
MemberAccountLogEntity entity = new MemberAccountLogEntity();
entity.setMemberName("35ns98w1");
List<MemberAccountLogEntity> list1 = memberAccountLogRepository.findAll(Example.of(entity));
log.info("mongoDB全部用户数量:{},详情:{}", list1.size(), list1);

// 添加条件,名字模糊匹配,添加排序
MemberAccountLogEntity entity1 = new MemberAccountLogEntity();
entity1.setMemberName("35");
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher(MemberAccountLogEntity.Fields.memberName, ExampleMatcher.GenericPropertyMatchers.contains());
Example<MemberAccountLogEntity> example = Example.of(entity1, matcher);
Sort sort = Sort.by(MemberAccountLogEntity.Fields.depositMoney).descending();
List<MemberAccountLogEntity> list2 = memberAccountLogRepository.findAll(example, sort);
log.info("mongoDB全部用户数量:{},详情:{}", list2.size(), list2);

// 分页
Sort sort1 = Sort.by(MemberAccountLogEntity.Fields.totalConsumption).descending();
PageRequest page = PageRequest.of(0, 10, sort1);
Page<MemberAccountLogEntity> list3 = memberAccountLogRepository.findAll(page);
log.info("mongoDB全部用户数量:{},当前分页详情:{}", list3.getTotalElements(), list3.getContent());

// 总数
long count = memberAccountLogRepository.count(example);
log.info("查询用户数量:{}", count);
}

/**
* 批量插入
*/
private void insertBatch(int count) {
List<MemberAccountLogEntity> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
MemberAccountLogEntity entity = new MemberAccountLogEntity();
entity.setId(IdUtil.getSnowflakeNextId());
entity.setMemberId(i + RandomUtil.randomString(6));
entity.setMemberName(i + RandomUtil.randomString(6));
entity.setTotalConsumption(RandomUtil.randomBigDecimal(BigDecimal.ZERO, BigDecimal.TEN));
entity.setDepositMoney(RandomUtil.randomBigDecimal(BigDecimal.ZERO, BigDecimal.TEN));
list.add(entity);
}
memberAccountLogRepository.insert(list);
}

/**
* 插入单挑
*/
private void insertOne() {
MemberAccountLogEntity entity = new MemberAccountLogEntity();
entity.setId(IdUtil.getSnowflakeNextId());
entity.setMemberId(RandomUtil.randomString(6));
entity.setMemberName(RandomUtil.randomString(6));
entity.setTotalConsumption(RandomUtil.randomBigDecimal(BigDecimal.ZERO, BigDecimal.TEN));
entity.setDepositMoney(RandomUtil.randomBigDecimal(BigDecimal.ZERO, BigDecimal.TEN));
memberAccountLogRepository.insert(entity);
}
}

3)MongoTemplate

对于某些复杂的查询,那么我们将会用到MongoTemplate.java

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package com.banmoon.execute;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.banmoon.dto.MangoAggregationDTO;
import com.banmoon.dto.MangoAggregationGroupByDTO;
import com.banmoon.entity.MemberAccountLogEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
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.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Slf4j
@Component
public class MongoTemplateExecute implements Runnable{

@Resource
private MongoTemplate mongoTemplate;

public static final String COLLECTION_NAME = "member_account_log";

@Override
public void run() {
simpleCurd();
aggregation();
}

/**
* 聚合操作
*/
private void aggregation() {
// count();
groupBy();
}

private void groupBy() {
// 构建查询match条件:
MatchOperation matchOperation = Aggregation.match(Criteria.where(MemberAccountLogEntity.Fields.memberName).ne(null));
// 构建分组聚合分析
GroupOperation groupOperation = Aggregation.group(MemberAccountLogEntity.Fields.memberId)
.first(MemberAccountLogEntity.Fields.memberName).as(MangoAggregationGroupByDTO.Fields.memberName)
.count().as(MangoAggregationGroupByDTO.Fields.count)
.max(MemberAccountLogEntity.Fields.depositMoney).as(MangoAggregationGroupByDTO.Fields.max)
.min(MemberAccountLogEntity.Fields.depositMoney).as(MangoAggregationGroupByDTO.Fields.min)
.avg(MemberAccountLogEntity.Fields.depositMoney).as(MangoAggregationGroupByDTO.Fields.avg)
.sum(MemberAccountLogEntity.Fields.totalConsumption).as(MangoAggregationGroupByDTO.Fields.sum);
// 整合生成聚合对象
TypedAggregation<MangoAggregationGroupByDTO> aggregation = Aggregation.newAggregation(MangoAggregationGroupByDTO.class, matchOperation, groupOperation);
// 查询
AggregationResults<MangoAggregationGroupByDTO> resultList = mongoTemplate.aggregate(aggregation, MangoAggregationGroupByDTO.class);
// 获取结果
List<MangoAggregationGroupByDTO> list = resultList.getMappedResults();
list.forEach(dto -> log.info("{}", JSONUtil.toJsonStr(dto)));
}

private void count() {
// 构建查询match条件:
MatchOperation matchOperation = Aggregation.match(Criteria.where(MemberAccountLogEntity.Fields.totalConsumption).gt(new BigDecimal("1")));
// 构建count操作,用“count”名称接收
CountOperation countOperation = Aggregation.count().as(MangoAggregationDTO.Fields.count);
// 整合生成聚合对象
Aggregation aggregation = Aggregation.newAggregation(matchOperation, countOperation);
// 查询你
AggregationResults<MangoAggregationDTO> resultList = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, MangoAggregationDTO.class);
// 获取结果
List<MangoAggregationDTO> aggregationList = resultList.getMappedResults();
log.info("count结果数量:{}", aggregationList.get(0).getCount());
}

private void simpleCurd() {
// 查询所有
List<MemberAccountLogEntity> allList = mongoTemplate.findAll(MemberAccountLogEntity.class);
log.info("所有会员数量:{}", allList.size());

// 新增
MemberAccountLogEntity entity = new MemberAccountLogEntity();
entity.setId(IdUtil.getSnowflakeNextId());
entity.setMemberName(RandomUtil.randomString(6));
entity.setMemberId(RandomUtil.randomString(6));
entity.setTotalConsumption(new BigDecimal("100"));
entity.setDepositMoney(RandomUtil.randomBigDecimal(BigDecimal.ZERO, BigDecimal.TEN));
mongoTemplate.save(entity, COLLECTION_NAME);

// 修改
Query query = new Query(Criteria.where(MemberAccountLogEntity.Fields.totalConsumption).gte(new BigDecimal("100")));
Update update = new Update();
update.set(MemberAccountLogEntity.Fields.depositMoney, new BigDecimal("99"));
mongoTemplate.updateFirst(query, update, MemberAccountLogEntity.class);

// 查询
Query query1 = new Query(Criteria.where(MemberAccountLogEntity.Fields.totalConsumption).gte(new BigDecimal("100")));
List<MemberAccountLogEntity> list = mongoTemplate.find(query1, MemberAccountLogEntity.class);
log.info("余额大于100的人:{}", list);

// 分页查询
Query query2 = new Query(Criteria.where(MemberAccountLogEntity.Fields.totalConsumption).gte(new BigDecimal("100")));
long count = mongoTemplate.count(query2, COLLECTION_NAME);
int pageSize = 10;
int pageIndex = 3;
query2.skip((pageIndex - 1) * pageSize).limit(pageSize);
List<MemberAccountLogEntity> list1 = mongoTemplate.find(query2, MemberAccountLogEntity.class, COLLECTION_NAME);
log.info("分页查询总数:{},当前页:{}", count, list1);

// 删除
Query query3 = new Query();
mongoTemplate.remove(query3, MemberAccountLogEntity.class);
}

}

三、最后

介绍了MongoRepository.javaMongoTemplate.java两种写法。

具体使用可能不是很全面,如果后面有新的,后续再进行补充。

我是半月,你我一同共勉!!!