一. spring-boot 融合cassandra
- maven 依赖
<!--cassandra 配置--> <!--<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-cassandra</artifactId> </dependency>--> //不要引入了,避免启动时,必须保证cassandra可用 <dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-core</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-mapping</artifactId> <version>3.4.0</version> </dependency>
- 属性文件配置
cassandra.cluster-name=test-cluster cassandra.keyspace-name=test cassandra.contact-points=ip1,ip2,ip3 cassandra.port=9042 cassandra.username=xiaoming cassandra.password=password
- config创建
@Configuration @ConditionalOnProperty(name = "use.db", havingValue = "cassandra") public class CassandraConfig { @Value("${cassandra.keyspace-name}") private String keyspaceName; @Value("${cassandra.contact-points}") private String host; /** * 端口 */ @Value("${cassandra.port}") private int port; /** * 集群名称 */ @Value("${cassandra.cluster-name}") private String clusterName; /** * 用户名 */ @Value("${cassandra.username}") private String userName; /** * 密码 */ @Value("${cassandra.password}") private String password; @Bean public Cluster cluster() { return Cluster.builder() .addContactPoints(host.split(",")) .withPort(port) .withClusterName(clusterName) .withCredentials(userName, password) .build(); } @Bean public NamingStrategy namingStrategy() { //java 驼峰命令, 对应cassandra我也选择驼峰命名, 个人喜好^-^ return new DefaultNamingStrategy(LOWER_CAMEL_CASE, LOWER_CAMEL_CASE); } @Bean public Session session(Cluster cluster) { Session session = cluster.connect(); setupKeyspace(session, keyspaceName); CassandraHolder.CASS_SESSION = session; return session; } private void setupKeyspace(Session session, String keyspace) { Map<String, Object> replication = new HashMap<>(); session.execute(createKeyspace(keyspace).ifNotExists().with().replication(replication)); session.execute("USE " + keyspace); } @Bean public MappingManager mappingManager(Session session, NamingStrategy namingStrategy) { PropertyMapper propertyMapper = new DefaultPropertyMapper().setNamingStrategy(namingStrategy); MappingConfiguration configuration = MappingConfiguration.builder().withPropertyMapper(propertyMapper).build(); MappingManager result = new MappingManager(session, configuration); CassandraHolder.MANAGER = result; return result; } }
- 改,查,删,批量保存
/** * 留给子类实现 */ protected Mapper<T> getMapper(Class<T> clazz) { return MANAGER != null ? MANAGER.mapper(clazz) : null; } public void save(T entity) { mapper().save(entity); } public int batchSave(List<T> list) { if (ArrayUtils.isEmpty(list)) { return 0; } BatchStatement batch = new BatchStatement(BatchStatement.Type.UNLOGGED); //任意一个节点写入成功 batch.setConsistencyLevel(ConsistencyLevel.ANY); try { for (T data : list) { Statement insert = insertInto(table()).values(column(), bindData(data)); batch.add(insert); if (batch.size() == 200) { CASS_SESSION.execute(batch); batch.clear(); } } CASS_SESSION.execute(batch); batch.clear(); } catch (Exception e) { log.error("批量存储失败:", e); } return list.size(); } public abstract T findOne(String id, String key); public void delete(T entity) { mapper().delete(entity); } /** * 一个典型的entity */ @Data @Table(name = "table") public class Test{ @PartitionKey private String pk; @ClusteringColumn private String ck; private String ip; private Date createTime; } /*-------------------------批操作实现子类部分代码 开始-----------------------*/ private String TABLE = "mobileIndex"; private String[] COLUMN = {"pk", "ck", "ip", "\"createTime\""}; private Mapper<Test> mapper; @Override protected String table() { return TABLE; } @Override protected String[] column() { return COLUMN; } @Override protected Object[] bindData(Test entity) { return new Object[]{entity.getPk(), entity.getCk(), entity.getIp(), entity.getCreateTime()}; } /*-------------------------批操作实现子类部分代码 结束-----------------------*/
二. cassandra 使用特殊点
使用cql建表时,如果表名或属性名想保持驼峰命名法,记得带上双引号,否则均会被定义成纯小写;