1. 概述
DataStax 发行版的 Apache Cassandra 是一个可用于生产环境的分布式数据库,兼容开源版本的 Cassandra。它在开源功能基础上增加了一些高级特性,例如增强的监控能力、更高效的批量处理和流式数据支持。
DataStax 还为其 Cassandra 发行版提供了官方 Java 客户端驱动。这个驱动高度可配置,既能充分利用 DataStax 专有功能,又能完全兼容开源版 Cassandra —— ✅ 一套代码,双端通吃。
本文将带你使用 DataStax Java Driver for Apache Cassandra 连接 Cassandra 数据库,并完成基础的数据操作。内容不讲废话,直奔实战。
2. Maven 依赖
要使用 DataStax Java Driver,首先得把依赖加进项目。
使用 Maven 的同学,在 pom.xml
中加入以下两个核心依赖:
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-core</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-query-builder</artifactId>
<version>4.10.0</version>
</dependency>
⚠️ 注意:示例中版本为 4.1.0,建议升级到较新稳定版(如 4.10.0+),避免踩到已知 bug。
java-driver-core
:驱动核心,负责连接、执行、结果处理java-driver-query-builder
:提供类型安全的 CQL 构建器,告别拼接字符串
3. 使用 DataStax 驱动
依赖搞定后,接下来就是实操环节。
3.1. 连接数据库
连接 Cassandra 的核心是创建一个 CqlSession
实例。
最简单的连接方式:
CqlSession session = CqlSession.builder().build();
✅ 默认行为:
- 联系点(contact point):
127.0.0.1:9042
- 本地数据中心:自动探测(不推荐生产使用)
实际开发中,我们通常需要自定义连接参数。封装一个连接管理类更便于复用:
public class CassandraConnector {
private CqlSession session;
public void connect(String node, Integer port, String dataCenter) {
CqlSessionBuilder builder = CqlSession.builder();
builder.addContactPoint(new InetSocketAddress(node, port));
builder.withLocalDatacenter(dataCenter); // 必须设置,否则多 DC 环境会报错
session = builder.build();
}
public CqlSession getSession() {
return this.session;
}
public void close() {
if (session != null) {
session.close();
}
}
}
📌 踩坑提醒:
withLocalDatacenter()
是必须的,否则会抛No local DC defined
异常- 生产环境建议配置多个 contact points 实现高可用
3.2. 创建 Keyspace
连接建立后,先创建命名空间(keyspace),相当于关系型数据库中的“数据库”。
使用 SchemaBuilder
构建 CQL 语句,避免手写字符串出错:
public class KeyspaceRepository {
private final CqlSession session;
public KeyspaceRepository(CqlSession session) {
this.session = session;
}
public void createKeyspace(String keyspaceName, int numberOfReplicas) {
CreateKeyspace createKeyspace = SchemaBuilder.createKeyspace(keyspaceName)
.ifNotExists()
.withSimpleStrategy(numberOfReplicas);
session.execute(createKeyspace.build());
}
public void useKeyspace(String keyspace) {
session.execute("USE " + CqlIdentifier.fromCql(keyspace));
}
}
📌 说明:
- 使用
SimpleStrategy
策略,适合单数据中心测试环境 - 多数据中心生产环境应使用
NetworkTopologyStrategy
ifNotExists()
防止重复创建
3.3. 创建表
定义一个 Video
实体类作为示例:
public class Video {
private UUID id;
private String title;
private Instant creationDate;
// 构造方法、getter/setter 省略
}
接着创建对应的表结构:
public class VideoRepository {
private static final String TABLE_NAME = "videos";
private final CqlSession session;
public VideoRepository(CqlSession session) {
this.session = session;
}
public void createTable() {
createTable(null);
}
public void createTable(String keyspace) {
CreateTable createTable = SchemaBuilder.createTable(TABLE_NAME)
.withPartitionKey("video_id", DataTypes.UUID)
.withColumn("title", DataTypes.TEXT)
.withColumn("creation_date", DataTypes.TIMESTAMP);
executeStatement(createTable.build(), keyspace);
}
private ResultSet executeStatement(SimpleStatement statement, String keyspace) {
if (keyspace != null) {
statement = statement.setKeyspace(CqlIdentifier.fromCql(keyspace));
}
return session.execute(statement);
}
}
✅ 方法重载设计的好处:
createTable()
:在当前 session 使用的 keyspace 中建表createTable(keyspace)
:指定 keyspace 建表,不依赖当前 session 状态
这种设计更灵活,适合多租户或模块化系统。
3.4. 插入数据
插入数据推荐使用 预编译语句(PreparedStatement) + 绑定参数(BoundStatement),性能更高且防注入。
public UUID insertVideo(Video video, String keyspace) {
UUID videoId = UUID.randomUUID();
video.setId(videoId);
RegularInsert insertInto = QueryBuilder.insertInto(TABLE_NAME)
.value("video_id", QueryBuilder.bindMarker())
.value("title", QueryBuilder.bindMarker())
.value("creation_date", QueryBuilder.bindMarker());
SimpleStatement insertStatement = insertInto.build();
if (keyspace != null) {
insertStatement = insertStatement.setKeyspace(keyspace);
}
PreparedStatement preparedStatement = session.prepare(insertStatement);
BoundStatement statement = preparedStatement.bind()
.setUuid(0, video.getId())
.setString(1, video.getTitle())
.setInstant(2, video.getCreationDate());
session.execute(statement);
return videoId;
}
📌 关键点:
bindMarker()
生成占位符?
prepare()
提升重复执行效率- 按索引设置值(从 0 开始),也可按名称绑定
3.5. 查询数据
查询同样使用 QueryBuilder 构建语句,简洁又安全:
public List<Video> selectAll(String keyspace) {
Select select = QueryBuilder.selectFrom(TABLE_NAME).all();
ResultSet resultSet = executeStatement(select.build(), keyspace);
List<Video> result = new ArrayList<>();
resultSet.forEach(row -> result.add(
new Video(
row.getUuid("video_id"),
row.getString("title"),
row.getInstant("creation_date")
)
));
return result;
}
⚠️ 注意:
ResultSet
是迭代器模式,不要多次遍历- 推荐尽早转换为 POJO 列表,避免 session 关闭后无法读取
3.6. 完整示例
把上面所有组件串起来跑一遍:
public class Application {
private static final Logger LOG = LoggerFactory.getLogger(Application.class);
public void run() {
CassandraConnector connector = new CassandraConnector();
connector.connect("127.0.0.1", 9042, "datacenter1");
CqlSession session = connector.getSession();
KeyspaceRepository keyspaceRepo = new KeyspaceRepository(session);
keyspaceRepo.createKeyspace("testKeyspace", 1);
keyspaceRepo.useKeyspace("testKeyspace");
VideoRepository videoRepo = new VideoRepository(session);
videoRepo.createTable();
videoRepo.insertVideo(new Video("视频1", Instant.now()), "testKeyspace");
videoRepo.insertVideo(new Video("视频2", Instant.now().minus(1, ChronoUnit.DAYS)), "testKeyspace");
List<Video> videos = videoRepo.selectAll("testKeyspace");
videos.forEach(video -> LOG.info(video.toString()));
connector.close();
}
}
执行结果(日志输出):
INFO com.example.Application - [id:733249eb-914c-4153-8698-4f58992c4ad4, title:视频1, creationDate: 2019-07-10T19:43:35.112Z]
INFO com.example.Application - [id:a6568236-77d7-42f2-a35a-b4c79afabccf, title:视频2, creationDate: 2019-07-09T19:43:35.181Z]
数据成功落库,收工。
4. 总结
本文带你快速上手 DataStax Java Driver 的核心用法:
- ✅ 添加 Maven 依赖
- ✅ 建立连接(CqlSession)
- ✅ 操作 Keyspace 与表
- ✅ 使用 PreparedStatement 插入数据
- ✅ 查询并映射结果
整个过程简单粗暴,没有多余的理论铺垫。适合有数据库经验的开发者直接套用。
📌 源码已托管至 GitHub:https://github.com/baeldung/java-cassandra
后续可深入学习:
- 异步执行(Async API)
- 自定义类型映射(Codec)
- 重试策略与负载均衡
- 批量操作与事务模拟
Cassandra 的优势在于高写入、高可用,搭配 DataStax Driver 能充分发挥其潜力。生产项目中建议结合连接池、监控和熔断机制使用。