Spring Boot Cassandra:无需单独主键类实现复合主键Repository
在Spring Boot Cassandra中用单实体类实现复合主键与Repository
完全可以不用单独创建主键类,直接在标注@Table的实体类中保留这三个复合主键字段,同时正常实现Spring Data Repository,具体方案如下:
1. 定义实体类
直接在实体类中用@PrimaryKeyColumn标注复合主键字段,同时让实体类实现Serializable(Cassandra主键要求序列化):
import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; import org.springframework.data.cassandra.core.mapping.PrimaryKeyType; import org.springframework.data.cassandra.core.mapping.Table; import java.io.Serializable; import java.util.Date; @Table("your_target_table") public class YourEntity implements Serializable { @PrimaryKeyColumn(name = "stream", ordinal = 0, type = PrimaryKeyType.PARTITIONED) private int stream; @PrimaryKeyColumn(name = "entity", ordinal = 1, type = PrimaryKeyType.PARTITIONED) private int entity; @PrimaryKeyColumn(name = "date", ordinal = 2, type = PrimaryKeyType.CLUSTERED) private Date date; // 其他业务字段 private String content; // 生成getter、setter、构造方法 }
2. 实现Repository接口
根据主键的使用习惯,有两种常见的Repository定义方式:
方式一:使用MapId作为主键类型
MapId是Spring Data提供的键值对形式主键,键名要和@PrimaryKeyColumn的name属性完全匹配:
import org.springframework.data.cassandra.repository.CassandraRepository; import org.springframework.data.cassandra.repository.MapId; public interface YourEntityRepository extends CassandraRepository<YourEntity, MapId> { // 自定义查询方法示例:根据分区键stream和entity查询 List<YourEntity> findByStreamAndEntity(int stream, int entity); }
使用findById查询时,构建MapId即可:
MapId primaryKey = MapId.id("stream", 1001, "entity", 2002, "date", new Date()); YourEntity entity = yourEntityRepository.findById(primaryKey).orElse(null);
方式二:使用TupleId作为主键类型(Spring Data Cassandra 2.0+支持)
TupleId是基于元组的主键,元素顺序要和@PrimaryKeyColumn的ordinal顺序一致:
import org.springframework.data.cassandra.core.cql.TupleId; import org.springframework.data.cassandra.repository.CassandraRepository; public interface YourEntityRepository extends CassandraRepository<YourEntity, TupleId> { }
查询时构建TupleId:
TupleId primaryKey = TupleId.of(1001, 2002, new Date()); YourEntity entity = yourEntityRepository.findById(primaryKey).orElse(null);
注意事项
- 实体类必须实现
Serializable,否则Cassandra无法处理主键的序列化逻辑。 - 自定义查询方法时,方法名要符合Spring Data的命名规则,比如通过主键字段组合查询时,直接用字段名拼接即可。
内容的提问来源于stack exchange,提问作者Duncan Krebs
相关产品推荐
相关产品推荐

