本文共 3897 字,大约阅读时间需要 12 分钟。
隐去业务相关内容,使用过程如下:
1.分析需求,设计实体类;重构则阅读目前代码,梳理业务逻辑,重新设计实体类
2.根据Cassandra特性和业务需要设计数据库表
Cassandra的Primary key也要保证数据的唯一性标识,但是其更大的作用是服务于查询,也就是说Cassandra的主键更多是面向于业务来设计的,且Cassandra的表的primary key不能动态改变。
Cassandra主键包含了两个部分,PartitionKey和ClusterKey。在说明这两个key之前需要简单的介绍一下Cassandra的一些基本特性,在关系数据库的结构中当数据量增多的时候会导致单个表的数据查询性能下降,设计者也缺少好的策略去自动分割这些大量的数据。Cassandra则是采用partition来对于数据进行划分保存,在良好设计的情况下Cassandra就会按照定义的策略自动对数据进行分区,而PartitionKey就是Cassandra分区的依据,通过一个一致性hash函数计算这个PartitionKey的token进而直接找到其所在的分区。
Cassandra对于查询的支持很弱,限制如下:
Cassandra的查询必须在主键列上,或者查询的字段有二级索引。只有主键支持group by。
分区主键(PartitionKey第一主键)只能用=号查询。使用分区主键查询的话,需要指定全部的分区主键,不能使用部分分区主键查询。
对于排序主键(ClusteringKey第二主键),可以使用>,<,>=,<=来查询,如果前面有分区主键,可以直接用。如果只使用排序主键来查询的话,只能使用排序主键的第一个来查询,并且使用allow filtering;或者使用排序主键的第一个、第二个一起来查询,就是说要排序主键要有第一个才能使用第二个,有第二个才能使用第三个。要查询的字段并没有在primary key中导致只能开启全表扫描查询,严重影响性能。
3.在开发环境windows环境中安装Cassandra并启动,可安装可视化工具NoSQL Manager for Cassandra
4.代码编写
1)引入maven依赖com.datastax.cassandra相关,包括cassandra-driver-core,cassandra-driver-mapping实体映射等,此处注意guava版本。
2)Configuration:配置类中创建Cluster和Session用于连接cassandra。Cluster对象是驱动程序的主入口点,它保存着真实Cassandra集群的状态(尤其是元数据);Cluster是线程安全的,一个Cassandra集群创建一个Cluster的单例,整个应用用这一个单例即可。Session用来执行查询的,而且它也是线程安全的,同样也应该重复利用。设置NamingStrategy实体字段使用驼峰,表中使用下划线分隔。
3)Entity:根据设计编写实体并加上相应注解。
4)Repository:针对实体创建Repository,使用QueryBuilder组装查询语句。调用session的execute来发送一个查询到Cassandra,execute返回一个Resultset(结果集),这个结果集就是必要的列的行集合。使用Mapper来做映射(使用MappingManager生成Mapper<T>),或者直接从得到的Row中获取数据。
新增操作较简单略过。(mapper.save(data))
由于前面提到的业务需求,查询需用到group by,cassandra的group by与查询的规则一样,也是需要按排序主键顺序来进行,不能跳过中间某个字段,所以四个查询分别是:
SELECT report_type,income_outcome_type,sum(amount) AS amount FROM tb_report WHERE cost_time>beginTime AND cost_time<endTime GROUP BY report_type,income_outcome_type ALLOW FILTERING;
SELECT report_type,income_outcome_type,park_id,sum(amount) AS amount FROM tb_report WHERE cost_time>beginTime AND cost_time<endTime GROUP BY report_type,income_outcome_type,park_id ALLOW FILTERING;
SELECT report_type,report_item,sum(amount) AS amount FROM tb_report WHERE income_outcome_type=22 AND cost_time>beginTime AND cost_time<endTime GROUP BY report_type,income_outcome_type,park_id,report_item ALLOW FILTERING;
SELECT report_type,park_id,report_item,sum(amount) AS amount FROM tb_report WHERE income_outcome_type=22 AND cost_time>beginTime AND cost_time<endTime GROUP BY report_type,income_outcome_type,park_id,report_item ALLOW FILTERING;
后两个可以合为同一个查询。
5)Service:根据业务需求编写或重构。
对该数据库的操作主要分为两类,一个是新增,一个是查询。新增包括原先的新增和修改,原先查询出数据在此基础上增加这次的金额的操作改为直接新增插入数据库。查询则调用Repository的方法,获取数据之后,再进行业务上的处理,得到所需的数据。让旧的统计service和新的统计service实现同一个接口,这样只要修改xml配置文件,所有调用到统计的地方的实例变成了新的service实例。删改冗余重复的代码如大量的if或switch判断。
使用过程中的问题合集:
1.
2.ClassNotFoundException: com.google.common.util.concurrent.FutureFallback
使用19.0以下的版本的guava
maven Update
3.[com.datastax.driver.core.Native] Could not load JNR C Library, native system calls through this library will not be available
java.lang.UnsatisfiedLinkError: unknown
at jnr.ffi.provider.jffi.NativeLibrary.loadNativeLibraries(NativeLibrary.java:87)4.java实体中字段与库中字段对应关系
@Bean
public MappingManager mappingManager(Session session) { final PropertyMapper propertyMapper = new DefaultPropertyMapper() .setNamingStrategy(new DefaultNamingStrategy(NamingConventions.LOWER_CAMEL_CASE, NamingConventions.LOWER_SNAKE_CASE)); final MappingConfiguration configuration = MappingConfiguration.builder().withPropertyMapper(propertyMapper).build(); return new MappingManager(session, configuration); }其中new DefaultNamingStrategy(NamingConventions.LOWER_CAMEL_CASE, NamingConventions.LOWER_SNAKE_CASE)表示代码中使用驼峰,数据库字段使用下划线分隔。
5.Invalid ordering value 1 for annotation @ClusteringColumn of property 'xxx', was expecting 0
注意@ClusteringColumn(x)注解的使用,按顺序递增,不写默认是0
6.group by currently only support groups of columns following their declared order ...
查询需用到group by,cassandra的group by与查询的规则一样,也是需要按排序主键顺序来进行,不能跳过中间某个字段
group by要按排序主键顺序不能跳过
转载地址:https://blog.csdn.net/u010898743/article/details/103711488 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!