本文目录导读:

我将为您提供几个Java中使用NoSQL数据库的完整案例,涵盖主流NoSQL数据库的使用方法。
MongoDB案例(文档型数据库)
Maven依赖
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.9.1</version>
</dependency>
基础操作案例
import com.mongodb.client.*;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import org.bson.Document;
import java.util.Arrays;
import java.util.Date;
public class MongoDBExample {
public static void main(String[] args) {
// 1. 连接MongoDB
MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
// 2. 获取数据库和集合
MongoDatabase database = mongoClient.getDatabase("shop");
MongoCollection<Document> collection = database.getCollection("users");
// 3. 插入文档
Document user = new Document("name", "张三")
.append("age", 25)
.append("email", "zhangsan@example.com")
.append("createdAt", new Date())
.append("address", new Document()
.append("city", "北京")
.append("street", "朝阳区")
.append("zipCode", "100000"));
collection.insertOne(user);
System.out.println("插入成功,ID: " + user.getObjectId("_id"));
// 4. 批量插入
collection.insertMany(Arrays.asList(
new Document("name", "李四").append("age", 30),
new Document("name", "王五").append("age", 28)
));
// 5. 查询文档
// 普通查询
Document found = collection.find(Filters.eq("name", "张三")).first();
System.out.println("查询结果: " + found);
// 条件查询
FindIterable<Document> results = collection.find(
Filters.and(
Filters.gte("age", 25),
Filters.lt("age", 30)
)
);
for (Document doc : results) {
System.out.println("符合条件: " + doc);
}
// 6. 更新文档
collection.updateOne(
Filters.eq("name", "张三"),
Updates.combine(
Updates.set("age", 26),
Updates.inc("visits", 1)
)
);
// 7. 删除文档
collection.deleteOne(Filters.eq("name", "李四"));
// 8. 索引操作
collection.createIndex(new Document("email", 1));
collection.createIndex(new Document("age", -1).append("name", 1));
mongoClient.close();
}
}
Redis案例(键值存储)
Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.1.0</version>
</dependency>
Spring Boot + Redis案例
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.stereotype.Service;
@Service
public class RedisCacheService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 缓存用户信息
public void cacheUserInfo(String userId, UserInfo userInfo) {
String key = "user:" + userId;
// 使用Hash存储用户信息
HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
hashOps.put(key, "name", userInfo.getName());
hashOps.put(key, "age", userInfo.getAge());
hashOps.put(key, "email", userInfo.getEmail());
// 设置过期时间(10分钟)
redisTemplate.expire(key, 10, TimeUnit.MINUTES);
}
// 获取用户信息
public UserInfo getUserInfo(String userId) {
String key = "user:" + userId;
HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
UserInfo userInfo = new UserInfo();
userInfo.setName((String) hashOps.get(key, "name"));
userInfo.setAge((Integer) hashOps.get(key, "age"));
userInfo.setEmail((String) hashOps.get(key, "email"));
return userInfo;
}
// 缓存商品列表(使用List)
public void cacheProductList(String categoryId, List<Product> products) {
String key = "products:category:" + categoryId;
redisTemplate.delete(key);
// 批量添加
products.forEach(product ->
redisTemplate.opsForList().rightPush(key, product)
);
}
// 使用Redis实现分布式锁
public boolean tryLock(String lockKey, long timeout) {
// 使用SetNX命令
return Boolean.TRUE.equals(
redisTemplate.opsForValue().setIfAbsent(
lockKey,
Thread.currentThread().getId(),
timeout,
TimeUnit.SECONDS
)
);
}
// 计数器功能
public long incrementCounter(String counterKey) {
return redisTemplate.opsForValue().increment(counterKey);
}
}
Cassandra案例(列族存储)
Maven依赖
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-core</artifactId>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-query-builder</artifactId>
<version>4.15.0</version>
</dependency>
Cassandra操作案例
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.*;
import com.datastax.oss.driver.api.querybuilder.QueryBuilder;
public class CassandraExample {
public static void main(String[] args) {
// 1. 连接Cassandra
try (CqlSession session = CqlSession.builder()
.addContactPoint(new InetSocketAddress("localhost", 9042))
.withLocalDatacenter("datacenter1")
.withKeyspace("mykeyspace")
.build()) {
// 2. 创建表
session.execute("""
CREATE TABLE IF NOT EXISTS users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT,
age INT,
city TEXT,
created_at TIMESTAMP
)
""");
// 3. 插入数据
PreparedStatement insert = session.prepare(
"INSERT INTO users (user_id, name, email, age, city, created_at) VALUES (?, ?, ?, ?, ?, ?)"
);
BoundStatement bound = insert.bind(
UUID.randomUUID(),
"张三",
"zhangsan@example.com",
25,
"北京",
new Date()
);
session.execute(bound);
// 4. 查询数据
ResultSet resultSet = session.execute("SELECT * FROM users WHERE user_id = ?", userId);
Row row = resultSet.one();
if (row != null) {
System.out.println("用户: " + row.getString("name"));
System.out.println("邮箱: " + row.getString("email"));
System.out.println("年龄: " + row.getInt("age"));
}
// 5. 索引查询(Cassandra 3.4+)
session.execute("CREATE INDEX IF NOT EXISTS idx_users_age ON users(age)");
ResultSet ageResults = session.execute("SELECT * FROM users WHERE age > 20 ALLOW FILTERING");
// 6. 更新数据
session.execute(
"UPDATE users SET age = 26, city = '上海' WHERE user_id = ?",
userId
);
// 7. 使用QueryBuilder
Statement select = QueryBuilder.selectFrom("users")
.columns("user_id", "name", "email")
.whereColumn("city").isEqualTo(QueryBuilder.literal("北京"))
.build();
ResultSet queryBuilderResult = session.execute(select);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Elasticsearch案例(搜索引擎)
Maven依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.9</version>
</dependency>
搜索引擎案例
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
public class ElasticsearchExample {
private RestHighLevelClient client;
public ElasticsearchExample() {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
}
// 创建索引
public void createIndex(String indexName) throws IOException {
CreateIndexRequest request = new CreateIndexRequest(indexName);
request.mapping("""
{
"properties": {
"title": { "type": "text", "analyzer": "ik_max_word" },
"content": { "type": "text", "analyzer": "ik_max_word" },
"publishDate": { "type": "date" },
"category": { "type": "keyword" }
}
}
""", XContentType.JSON);
client.indices().create(request, RequestOptions.DEFAULT);
}
// 添加文档
public void addDocument(String indexName, String id, String title,
String content, String category) throws IOException {
IndexRequest request = new IndexRequest(indexName);
request.id(id);
Map<String, Object> document = new HashMap<>();
document.put("title", title);
document.put("content", content);
document.put("category", category);
document.put("publishDate", new Date());
request.source(document);
client.index(request, RequestOptions.DEFAULT);
}
// 搜索文档
public List<Map<String, Object>> search(String indexName,
String query) throws IOException {
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建搜索查询
sourceBuilder.query(
QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery("title", query))
.should(QueryBuilders.matchQuery("content", query))
.minimumShouldMatch(1)
);
// 分页设置
sourceBuilder.from(0);
sourceBuilder.size(10);
// 排序
sourceBuilder.sort("publishDate", SortOrder.DESC);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
List<Map<String, Object>> results = new ArrayList<>();
for (SearchHit hit : response.getHits().getHits()) {
results.add(hit.getSourceAsMap());
}
return results;
}
// 删除文档
public void deleteDocument(String indexName, String id) throws IOException {
DeleteRequest request = new DeleteRequest(indexName, id);
client.delete(request, RequestOptions.DEFAULT);
}
}
Neo4j案例(图数据库)
Maven依赖
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>5.9.0</version>
</dependency>
图数据库案例
import org.neo4j.driver.*;
import static org.neo4j.driver.Values.parameters;
public class Neo4jExample implements AutoCloseable {
private final Driver driver;
public Neo4jExample(String uri, String user, String password) {
driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
}
// 创建社交网络节点和关系
public void createSocialNetwork() {
try (Session session = driver.session()) {
session.run("CREATE (zhangsan:Person {name: '张三', age: 30})");
session.run("CREATE (lisi:Person {name: '李四', age: 28})");
// 创建关系
session.run("""
MATCH (a:Person {name: '张三'}), (b:Person {name: '李四'})
CREATE (a)-[r:FOLLOWS]->(b)
""");
// 创建朋友关系
session.run("""
MATCH (a:Person {name: '张三'}), (b:Person {name: '李四'})
CREATE (a)-[r:FRIEND_OF {since: 2020}]->(b)
""");
}
}
// 查询朋友关系
public void findFriends(String personName) {
try (Session session = driver.session()) {
Result result = session.run(
"MATCH (p:Person {name: $name})-[:FRIEND_OF]->(friends) RETURN friends.name AS name, friends.age AS age",
parameters("name", personName)
);
while (result.hasNext()) {
Record record = result.next();
System.out.println("朋友: " + record.get("name").asString() +
",年龄: " + record.get("age").asInt());
}
}
}
// 查找推荐好友(朋友的朋友)
public void findFriendSuggestions(String personName) {
try (Session session = driver.session()) {
Result result = session.run("""
MATCH (p:Person {name: $name})-[:FRIEND_OF]->(friend)-[:FRIEND_OF]->(suggestion)
WHERE suggestion.name <> $name
AND NOT (p)-[:FRIEND_OF]->(suggestion)
RETURN DISTINCT suggestion.name AS name, suggestion.age AS age
LIMIT 5
""",
parameters("name", personName));
while (result.hasNext()) {
Record record = result.next();
System.out.println("推荐好友: " + record.get("name").asString());
}
}
}
// 删除关系
public void removeFriend(String person1, String person2) {
try (Session session = driver.session()) {
session.run("""
MATCH (a:Person {name: $name1})-[r]->(b:Person {name: $name2})
DELETE r
""",
parameters("name1", person1, "name2", person2));
}
}
@Override
public void close() {
driver.close();
}
}
性能优化建议
MongoDB优化
public class MongoDBPerformance {
// 使用批量插入提高性能
public void bulkInsert(List<Document> documents) {
MongoCollection<Document> collection = getCollection();
// 每批1000条
BulkWriteOptions bulkWriteOptions = new BulkWriteOptions().ordered(false);
List<WriteModel<Document>> bulkOperations = documents.stream()
.map(doc -> new InsertOneModel<>(doc))
.collect(Collectors.toList());
BulkWriteResult result = collection.bulkWrite(bulkOperations, bulkWriteOptions);
}
// 查询优化 - 使用投影只获取必要字段
public void optimizedQuery() {
MongoCollection<Document> collection = getCollection();
Document projection = new Document("name", 1)
.append("age", 1)
.append("_id", 0);
FindIterable<Document> iterable = collection.find(
new Document("age", new Document("$gt", 25))
).projection(projection).limit(100);
// 使用batch size
iterable.batchSize(500);
}
}
Redis优化
@Component
public class RedisPerformance {
@Autowired
private StringRedisTemplate redisTemplate;
// 使用pipeline批量操作
public void batchOperations() {
List<Object> results = redisTemplate.executePipelined(
(RedisCallback<Object>) connection -> {
connection.set("key1".getBytes(), "value1".getBytes());
connection.set("key2".getBytes(), "value2".getBytes());
connection.get("key1".getBytes());
return null;
}
);
}
// 使用Lua脚本实现原子操作
public void useLuaScript() {
DefaultRedisScript<String> script = new DefaultRedisScript<>();
script.setScriptText("""
local current = tonumber(redis.call('get', KEYS[1]))
local new = tonumber(ARGV[1])
if current >= new then
return current
end
redis.call('set', KEYS[1], new)
return new
""");
script.setResultType(String.class);
redisTemplate.execute(script,
Arrays.asList("counter"),
"100"
);
}
}
这些案例展示了Java中主流NoSQL数据库的基本使用方法:
- MongoDB:文档型,适合灵活的数据结构和快速开发
- Redis:键值型,适合缓存、会话管理和实时统计
- Cassandra:列族型,适合大规模分布式系统
- Elasticsearch:搜索引擎,适合全文搜索和分析
- Neo4j:图型,适合关系密集型数据
选择NoSQL数据库时,应根据业务需求考虑:
- 数据结构特征(结构化、半结构化、非结构化)
- 查询模式(等值查询、范围查询、全文搜索、图查询)
- 扩展需求(水平扩展、垂直扩展)
- 一致性要求(强一致、最终一致)
- 运维复杂度
每个数据库都有其特定的优点和适用场景,合理选择能够大大提高应用性能和开发效率。