概念:
MongoDB采用集合(Collection)存储数据,每条数据就是一个文档(Document)。文档结构很好理解,其实就是我们常用的JSON,一个JSON就是一条记录。
集合相当于MySQL中的数据表,但是没有固定的表结构。集合有什么字段,取决于保存在其中的数据。
例如:
[
{
"_id": 1,
"name": "Alice",
"age": 25,
"skills": ["Java", "Python"]
},
{
"_id": 2,
"name": "Bob",
"age": 30,
"skills": ["JavaScript"]
}
]
例如:在我的项目当中message集合中JSON数据的结构要求
字段 | 类型 | 备注 |
---|---|---|
_id | UUID | 自动生成的主键值 |
uuid | UUID | UUID值,并且设置有唯一性索引,防止消息被重复消费 |
senderId | Integer | 发送者ID,就是用户ID。如果是系统自动发出,这个ID值是0 |
senderPhoto | String | 发送者的头像URL。在消息页面要显示发送人的头像 |
senderName | String | 发送者名称,也就是用户姓名。在消息页面要显示发送人的名字 |
msg | String | 消息正文 |
sendTime | Date | 发送时间 |
MongoDB与MySQL的区别:
MongoDB:
- 高性能,适用于大数据量和高并发写入。
- 不能像mysql一样使用join进行复杂的查询。
MySQL:
- 可以进行复杂的查询,适合多表的情况。
使用RabbitMQ对数据写入到MongoDB进行优化:
在系统发送消息给用户时,会产生大量的数据,如果一次性写入到数据库当中,那数据库的压力会很大,这时我们就可以用RabbitMQ的来**"削峰填谷"**(比如系统发送通知给每一个用户,但用户的在线时间不同,我们就可以先把消息发送到RabbitMQ消息队列,等到用户上线后,用异步线程从消息队列MQ中,接收消息,然后再写入到数据库当中,这样就实现了削峰填谷)。
MongoDB的CRUD怎么写:
我这里使用的是 MongoTemplate
对 MongoDB 进行 CRUD操作,以下是详细的实现方法:
1. 插入数据
使用 MongoTemplate
的 save
方法。
插入单条数据
java
@Autowired
private MongoTemplate mongoTemplate;
public String insertOne(MessageEntity entity) {
// 插入数据
entity = mongoTemplate.save(entity); // 如果有 _id,save 会更新文档;没有 _id 会插入新文档
return entity.get_id();
}
等价于:
java
INSERT INTO MessageEntity (id, sendTime, messageContent, ...)
VALUES (uuid(), CURRENT_TIMESTAMP, 'Message content', ...);
插入多条数据
java
public List<MessageEntity> insertMany(List<MessageEntity> entities) {
// 插入多条数据
return mongoTemplate.insert(entities, MessageEntity.class); // insert 批量插入
}
2. 查询数据
使用 find
和 findOne
方法进行查询。
查询所有数据
java
public List<MessageEntity> findAll() {
return mongoTemplate.findAll(MessageEntity.class); // 查询整个集合的所有文档
}
等价于:
java
SELECT * FROM MessageEntity;
条件查询
java
public List<MessageEntity> findByCondition(String fieldName, Object value) {
Query query = new Query(Criteria.where(fieldName).is(value)); // 构造条件
return mongoTemplate.find(query, MessageEntity.class); // 根据条件查询
}
查询单条数据
java
public MessageEntity findOne(String id) {
Query query = new Query(Criteria.where("_id").is(id)); // 按 _id 查询
return mongoTemplate.findOne(query, MessageEntity.class);
}
分页与排序查询
java
public List<MessageEntity> findWithPagination(int page, int size) {
Query query = new Query()
.skip((page - 1) * size) // 跳过文档数
.limit(size) // 每页大小
.with(Sort.by(Sort.Order.desc("sendTime"))); // 按 sendTime 倒序
return mongoTemplate.find(query, MessageEntity.class);
}
等价于:
java
SELECT * FROM MessageEntity
ORDER BY sendTime DESC
LIMIT 10 OFFSET 10;
聚合查询
java
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(Criteria.where("age").gt(20))
);
List<EntityClass> result = mongoTemplate.aggregate(agg, EntityClass.class, EntityClass.class).getMappedResults();
等价于:
java
SELECT * FROM collection WHERE age > 20;
3. 更新数据
使用 updateFirst
或 updateMulti
方法更新数据。
更新单条数据
java
public long updateOne(String id, String newField, Object newValue) {
Query query = new Query(Criteria.where("_id").is(id)); // 查询条件
Update update = new Update().set(newField, newValue); // 设置更新字段
UpdateResult result = mongoTemplate.updateFirst(query, update, MessageEntity.class);
return result.getModifiedCount(); // 返回修改的文档数量
}
更新多条数据
java
public long updateMany(String fieldName, Object oldValue, String newField, Object newValue) {
Query query = new Query(Criteria.where(fieldName).is(oldValue)); // 查询条件
Update update = new Update().set(newField, newValue); // 更新操作
UpdateResult result = mongoTemplate.updateMulti(query, update, MessageEntity.class);
return result.getModifiedCount(); // 返回修改的文档数量
}
替换文档
java
public void replace(String id, MessageEntity newEntity) {
mongoTemplate.save(newEntity); // save 会根据 _id 替换文档
}
4. 删除数据
使用 remove
方法删除文档。
删除单条数据
public long deleteOne(String id) {
Query query = new Query(Criteria.where("_id").is(id)); // 按 _id 删除
DeleteResult result = mongoTemplate.remove(query, MessageEntity.class);
return result.getDeletedCount(); // 返回删除的文档数量
}
删除多条数据
public long deleteMany(String fieldName, Object value) {
Query query = new Query(Criteria.where(fieldName).is(value)); // 构造条件
DeleteResult result = mongoTemplate.remove(query, MessageEntity.class);
return result.getDeletedCount(); // 返回删除的文档数量
}
删除集合
public void dropCollection() {
mongoTemplate.dropCollection(MessageEntity.class); // 删除整个集合
}