数据库对比:
选择MongoDB而不是MySQL作为日志中心项目的数据库,主要有以下几点原因:
MongoDB与MySQL的区别
-
数据模型:
- MongoDB:文档型数据库,采用灵活的JSON或BSON格式存储数据。可以处理非结构化或半结构化数据,支持动态模式(Schema-less),同一集合中的文档可以有不同的字段。
- MySQL:关系型数据库,通过表格形式存储结构化数据,具有固定的列和数据类型,有严格的模式要求。
-
查询语言:
- MongoDB:使用基于JSON的查询语言,语法灵活且易于理解,适合快速开发和动态查询。
- MySQL:使用SQL语言,具有强大的查询能力,更适合复杂的JOIN操作和事务处理。
-
扩展性:
- MongoDB:具备水平扩展能力,可以通过分片来增加性能和存储容量,适合大数据量和高并发场景。
- MySQL:一般是垂直扩展,虽然也可以通过主从复制等方式进行读写分离,但在处理海量数据时扩展性不如MongoDB。
-
一致性和事务管理:
- MongoDB:默认实现最终一致性,支持多文档事务,但相对复杂性较高。
- MySQL:提供强一致性和ACID事务支持,更适合需要高可靠性的应用。
两者优缺点总结
-
MongoDB优点:
- 灵活的数据模型,适合快速迭代和变化频繁的应用。
- 更好的处理非结构化数据能力。
- 高可扩展性,适合大数据和高并发环境。
-
MongoDB缺点:
- 事务支持相对较弱,不适合需要复杂事务的场景。
- 对于简单的CRUD操作,可能会出现性能问题,特别是在小数据量下。
-
MySQL优点:
- 强大的事务支持和复杂查询能力。
- 数据完整性和一致性保证,适合金融、银行等业务需求。
-
MySQL缺点:
- 固定的数据模型对于变化多端的应用不够灵活。
- 扩展性差,处理大规模数据时可能面临瓶颈。
是否可以同时使用MongoDB和MySQL?
MongoDB和MySQL可以同时使用,这种架构称为多数据库架构。在某些情况下,项目可能需要两者的优点,例如:
- 日志存储:使用MongoDB处理大量非结构化日志数据。
- 用户管理:使用MySQL来管理用户数据和业务逻辑,确保数据的一致性和完整性。
通过合理的架构设计和接口,两个数据库可以有效协同工作,满足不同模块的需求。
Mongodb的基本使用:
引入所需Maven依赖:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
</dependency>
配置MongoTemplate:
package com.swp.mongodbtest.demos.web.config;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
@Configuration
public class MongodbConfig {
// 连接到本地的mongodb,可设置为自己的远程mongodb数据库
@Bean
public MongoClient mongoClient() {
return MongoClients.create("mongodb://localhost:27017");
}
// 配置连接到mongodb的哪个数据库,这里连接的是“article”数据库
@Bean
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), "article");
}
}
创建“article”数据库下集合“comment”对应数据的实体类:
package com.swp.mongodbtest.demos.web.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String id;
private String name;
private Integer age;
}
对应的dao层:
package com.swp.mongodbtest.demos.web.dao;
import com.swp.mongodbtest.demos.web.po.User;
import org.springframework.data.mongodb.repository.MongoRepository;
// 创建一个接口来定义对MongoDB的操作,即定义一个Repository接口。使用Spring Data MongoDB提供的方法来进行简单的CRUD操作,复杂的业务逻辑可使用配置的mongoTemplate来操作
public interface UserRepository extends MongoRepository<User,String> {
}
创建Service层:
package com.swp.mongodbtest.demos.web.service.impl;
import com.swp.mongodbtest.demos.web.dao.UserRepository;
import com.swp.mongodbtest.demos.web.po.User;
import com.swp.mongodbtest.demos.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserRepository userRepository;
@Override
public void insertList(List<User> list){
userRepository.saveAll(list);
}
}
最后上测试:
package com.swp.mongodbtest;
import com.swp.mongodbtest.demos.web.po.User;
import com.swp.mongodbtest.demos.web.service.impl.UserServiceImpl;
import org.bson.types.ObjectId;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
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.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest
class MongodbTestApplicationTests {
@Autowired
MongoTemplate mongoTemplate;
@Autowired
UserServiceImpl userServiceImpl;
@Test
void contextLoads() {
ArrayList<User> list = new ArrayList<>();
User user_1 = new User(null, "张三", 18);
User user_2 = new User(null, "李四", 28);
list.add(user_1);
list.add(user_2);
// 添加数据到指定集合”comment“
mongoTemplate.save(user_1, "comment");
userServiceImpl.insertList(list);
// 可根据条件修改指定集合数据
Query query = Query.query(Criteria.where("name").is("张三"));
Update update = Update.update("age", 38);
// 更新一条数据
mongoTemplate.updateFirst(query, update, "comment");
// 更新多条数据
mongoTemplate.updateMulti(query, update, "comment");
// 更新数据,如果数据不存在就新增
mongoTemplate.upsert(query, update, "comment");
// 可根据条件查询指定集合相关数据
// 查询 name = “张三”
Query query2 = Query.query(Criteria.where("name").is("张三"));
List<User> users1 = mongoTemplate.find(query2, User.class, "comment");
System.out.println("users1 ----" + users1);
// 查询所有
List<User> users2 = mongoTemplate.findAll(User.class, "comment");
System.out.println("users2 ----" + users2);
// 分页查询 page页码,pageSize每页展示几个
int page = 1;
int pageSize = 10;
Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("name")));
Query query3 = new Query().with(pageable);
List<User> users3 = mongoTemplate.find(query3, User.class, "comment");
System.out.println("users3 ----" + users3);
// 查询多个
Query query4 = Query.query(Criteria.where("age").gte(18));
List<User> users4 = mongoTemplate.find(query4, User.class);
System.out.println("users4 ----" + users4);
// 查询数量
Criteria criteria = Criteria.where("name").is("张三")
.and("age").lte(50);
Query query5 = Query.query(criteria);
long count = this.mongoTemplate.count(query5, User.class,"comment");
System.out.println("数量为" + count);
// 删除指定集合数据,可添加删除条件
Query query1 = Query.query(Criteria.where("age").is(28));
mongoTemplate.remove(query1, "comment");
}
}
返回结果:
2024-09-22 17:00:44.080 INFO 13572 --- [ main] org.mongodb.driver.connection : Opened connection [connectionId{localValue:3, serverValue:84}] to localhost:27017
users1 ----[User(id=66efdcbc41414450ee3fb6f6, name=张三, age=38)]
users2 ----[User(id=66efdcbc41414450ee3fb6f6, name=张三, age=38), User(id=66efdcbc41414450ee3fb6f7, name=李四, age=28)]
users3 ----[User(id=66efdcbc41414450ee3fb6f7, name=李四, age=28), User(id=66efdcbc41414450ee3fb6f6, name=张三, age=38)]
users4 ----[User(id=66efdcbc41414450ee3fb6f6, name=张三, age=38), User(id=66efdcbc41414450ee3fb6f7, name=李四, age=28)]
数量为1