简介
在现代企业级开发中,MongoDB 和 Redis 是处理非结构化数据和高性能缓存的核心工具。MongoDB以其灵活的文档模型支持复杂数据结构的存储与查询,而Redis则通过内存数据库的特性实现了低延迟、高并发的数据访问。本文将从零开始,通过完整的开发步骤、详细的代码示例和企业级实践案例,带你全面掌握MongoDB与Redis的核心技术。无论你是初学者还是进阶开发者,都能通过本文构建扎实的NoSQL开发能力,并掌握在实际项目中高效整合框架的技巧。
MongoDB:非结构化数据的灵活存储
1. MongoDB基础概念与核心优势
MongoDB 是一种文档型数据库,以BSON(Binary JSON)格式存储数据,支持嵌套结构、动态模式和水平扩展。
1.1 核心特性
- 动态模式:无需预定义表结构,字段可动态添加或删除。
- 高可用性:通过副本集(Replica Set)实现自动故障转移。
- 水平扩展:通过分片(Sharding)实现大规模数据的分布式存储。
- 丰富的查询语言:支持聚合管道、全文搜索和地理空间查询。
1.2 适用场景
- 内容管理系统:存储博客文章、用户评论等非结构化数据。
- 实时分析:日志数据、用户行为记录的存储与分析。
- 物联网(IoT):设备传感器数据的高吞吐量写入。
2. MongoDB从零开始实战开发
2.1 环境搭建与连接
-
安装MongoDB
- 官网下载最新版本(当前为MongoDB 7.0)并安装。
- 启动服务:
mongod --dbpath=/data/db
-
连接MongoDB
使用MongoDB Java驱动连接数据库:import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; public class MongoDBExample { public static void main(String[] args) { String uri = "mongodb://localhost:27017"; try (MongoClient client = MongoClients.create(uri)) { System.out.println("Connected to MongoDB!"); } } }
2.2 核心数据操作
-
插入文档
import com.mongodb.client.MongoCollection; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Updates.*; public class InsertData { public static void main(String[] args) { try (MongoClient client = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> collection = client.getDatabase("mydb").getCollection("users"); Document user = new Document("name", "Alice") .append("email", "alice@example.com") .append("roles", Arrays.asList("user", "admin")); collection.insertOne(user); System.out.println("Document inserted!"); } } } -
查询文档
public class QueryData { public static void main(String[] args) { try (MongoClient client = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> collection = client.getDatabase("mydb").getCollection("users"); FindIterable<Document> result = collection.find(eq("name", "Alice")); for (Document doc : result) { System.out.println(doc.toJson()); } } } } -
更新文档
public class UpdateData { public static void main(String[] args) { try (MongoClient client = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> collection = client.getDatabase("mydb").getCollection("users"); collection.updateOne(eq("name", "Alice"), set("email", "alice_new@example.com")); System.out.println("Document updated!"); } } } -
删除文档
public class DeleteData { public static void main(String[] args) { try (MongoClient client = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> collection = client.getDatabase("mydb").getCollection("users"); collection.deleteOne(eq("name", "Alice")); System.out.println("Document deleted!"); } } }
2.3 高级功能实战
-
聚合查询
计算用户数量并按角色分组:public class Aggregation { public static void main(String[] args) { try (MongoClient client = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> collection = client.getDatabase("mydb").getCollection("users"); AggregateIterable<Document> result = collection.aggregate(Arrays.asList( new Document("$group", new Document("_id", "$roles").append("count", new Document("$sum", 1))) )); for (Document doc : result) { System.out.println(doc.toJson()); } } } } -
索引优化
创建复合索引提升查询性能:public class CreateIndex { public static void main(String[] args) { try (MongoClient client = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> collection = client.getDatabase("mydb").getCollection("users"); collection.createIndex(new Document("name", 1).append("email", 1)); System.out.println("Index created!"); } } }
Redis:高性能缓存与分布式锁
1. Redis基础概念与核心优势
Redis 是一个内存键值数据库,支持多种数据类型(字符串、哈希、列表、集合等),并提供了持久化、主从复制和分布式锁等功能。
1.1 核心特性
- 高性能:内存读写,单机吞吐量可达10万次/秒。
- 数据结构丰富:支持字符串、哈希、列表、集合、有序集合等。
- 分布式锁:通过
SETNX命令实现分布式场景下的资源互斥访问。 - 持久化:支持 RDB 快照和 AOF 日志两种持久化方式。
1.2 适用场景
- 缓存:热点数据的高速访问(如用户会话、商品详情)。
- 计数器:分布式系统中的全局计数(如点赞数、访问量)。
- 分布式锁:协调多个节点对共享资源的访问。
2. Redis从零开始实战开发
2.1 环境搭建与连接
-
安装Redis
- 官网下载最新版本(当前为Redis 7.2)并安装。
- 启动服务:
redis-server
-
连接Redis
使用Jedis客户端连接Redis:import redis.clients.jedis.Jedis; public class RedisExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); System.out.println("Connected to Redis!"); jedis.close(); } }
2.2 核心数据操作
-
字符串操作
public class StringOperations { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); // 存储 jedis.set("username", "Bob"); // 查询 String name = jedis.get("username"); System.out.println("Username: " + name); // 删除 jedis.del("username"); System.out.println("Key deleted!"); jedis.close(); } } -
哈希操作
public class HashOperations { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); // 存储 jedis.hset("user:1001", "name", "Charlie"); jedis.hset("user:1001", "email", "charlie@example.com"); // 查询 Map<String, String> user = jedis.hgetAll("user:1001"); System.out.println("User: " + user); // 删除 jedis.hdel("user:1001", "email"); System.out.println("Field deleted!"); jedis.close(); } } -
列表操作
public class ListOperations { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); // 存储 jedis.lpush("messages", "Hello", "World"); // 查询 List<String> messages = jedis.lrange("messages", 0, -1); System.out.println("Messages: " + messages); // 删除 jedis.ltrim("messages", 0, 0); System.out.println("List trimmed!"); jedis.close(); } } -
集合操作
public class SetOperations { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); // 存储 jedis.sadd("tags", "java", "redis", "nosql"); // 查询 Set<String> tags = jedis.smembers("tags"); System.out.println("Tags: " + tags); // 删除 jedis.srem("tags", "nosql"); System.out.println("Tag removed!"); jedis.close(); } }
2.3 高级功能实战
-
分布式锁实现
使用SETNX实现分布式锁:public class DistributedLock { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); String lockKey = "resource_lock"; String clientId = UUID.randomUUID().toString(); int expireTime = 10; // 锁过期时间(秒) // 尝试获取锁 Long result = jedis.setnx(lockKey, clientId); if (result == 1) { System.out.println("Lock acquired!"); // 执行业务逻辑 try { Thread.sleep(5000); // 模拟业务耗时 } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放锁 String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(clientId)); System.out.println("Lock released!"); } } else { System.out.println("Failed to acquire lock!"); } jedis.close(); } } -
缓存穿透与雪崩解决方案
- 缓存穿透:使用布隆过滤器拦截非法请求。
- 缓存雪崩:随机设置缓存过期时间。
- 缓存击穿:使用互斥锁重建缓存。
示例代码(缓存雪崩解决方案):
public class CacheSolution { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); String key = "product:1001"; String value = "Product 1001 data"; // 设置随机过期时间 int baseTTL = 3600; // 1小时 int randomTTL = baseTTL + new Random().nextInt(600); // 0~10分钟随机 jedis.setex(key, randomTTL, value); System.out.println("Cached with TTL: " + randomTTL + " seconds"); jedis.close(); } }
企业级开发中的MongoDB与Redis整合
1. Spring Boot整合MongoDB
1.1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
1.2 配置数据源
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mydb
1.3 创建实体类
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "users")
public class User {
@Id
private String id;
private String name;
private String email;
private List<String> roles;
// Getter和Setter方法
}
1.4 创建Repository接口
import org.springframework.data.mongodb.repository.MongoRepository;
public interface UserRepository extends MongoRepository<User, String> {
List<User> findByName(String name);
}
1.5 Service层实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void addUser(User user) {
userRepository.save(user);
}
public List<User> getUsersByName(String name) {
return userRepository.findByName(name);
}
}
1.6 Controller层实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<String> createUser(@RequestBody User user) {
userService.addUser(user);
return ResponseEntity.ok("User created successfully");
}
@GetMapping("/{name}")
public ResponseEntity<List<User>> getUsersByName(@PathVariable String name) {
return ResponseEntity.ok(userService.getUsersByName(name));
}
}
2. Spring Boot整合Redis
2.1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.2 配置数据源
spring:
redis:
host: localhost
port: 6379
2.3 创建缓存注解
import org.springframework.cache.annotation.Cacheable;
public class CacheUtil {
@Cacheable(value = "products", key = "#id")
public Product getProductById(String id) {
// 模拟数据库查询
return new Product(id, "Product " + id);
}
}
2.4 Service层实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private CacheUtil cacheUtil;
public Product getProduct(String id) {
return cacheUtil.getProductById(id);
}
}
2.5 Controller层实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/{id}")
public ResponseEntity<Product> getProduct(@PathVariable String id) {
return ResponseEntity.ok(productService.getProduct(id));
}
}
总结
MongoDB与Redis作为NoSQL领域的核心工具,分别在非结构化数据存储和高性能缓存方面展现了强大的能力。通过本文的详细讲解和代码示例,你已经掌握了从零开始搭建MongoDB与Redis项目的方法,并了解了如何在企业级开发中整合这些技术。无论是小型项目还是大型分布式系统,MongoDB与Redis都能显著提升开发效率和系统性能。现在,动手实践吧!