• 分布式数据库Cassandra


    目录

    一、概述

    1、简介 

    2、架构

    3、使用场景 

    二、安装

    三、基本概念

    1、数据模型

    列(Column)

    列族

    KeySpace

    节点(Node)

    集群(Cluster)

    2、数据类型

    基础类型

    集合类型 

    自定义数据类型

    四、操作

    1.客户端操作

    cqlsh的基本命令 

    CQL-查询语言

    Keyspace

    表操作

    索引操作

    CRUD操作

     2.JAVA操作


    一、概述

    1、简介 

             Apache Cassandra是高度可扩展的,高性能的分布式NoSQL数据库。 提供高可用性而无需担心单点故障。具有能够处理大量数据的分布式架构。 数据放置在具有多个复制因子的不同机器上,以获得高可用性,而无需担心单点故障。

    特性:

    • 弹性可扩展性 - Cassandra是高度可扩展的; 它允许添加更多的硬件以适应更多的客户和更多的数据根据要求。
    • 始终基于架构 - Cassandra没有单点故障,它可以连续用于不能承担故障的关键业务应用程序。
    • 快速线性性能 - Cassandra是线性可扩展性的,即它为你增加集群中的节点数量增加你的吞吐量。因此,保持一个快速的响应时间。
    • 灵活的数据存储 - Cassandra适应所有可能的数据格式,包括:结构化,半结构化和非结构化。它可以根据您的需要动态地适应变化的数据结构。
    • 便捷的数据分发 - 可以在多个数据中心之间复制数据,可以灵活地在需要时分发数据。
    • 事务支持 - Cassandra支持属性,如原子性,一致性,隔离和持久性(ACID)。
    • 快速写入 - Cassandra被设计为在廉价的商品硬件上运行。 它执行快速写入,并可以存储数百TB的数据,而不牺牲读取效率。

    2、架构

            Cassandra中的数据分布在集群中的所有节点上,处理多个节点之间的大数据工作负载,而无需担心单点故障。各个节点是相互独立的,但同时与其他节点互连,平等地址。每个阶段都可以进行读写操作,如果其中一个节点发生故障,其他节点也可以继续提供读写请求。

            在Cassandra中,集群中的节点作为给定数据片段的副本。 如果某些节点以超时值响应,Cassandra会将最新的值返回给客户端。 返回最新值后,Cassandra会在后台执行读取修复,以更新旧值。

     结构组成:

    • 节点(Node):Cassandra节点是存储数据的地方。
    • 数据中心(Data center):数据中心是相关节点的集合。
    • 集群(Cluster):集群是包含一个或多个数据中心的组件。
    • 提交日志(Commit log):每个写入操作都将写入提交日志,用户异常恢复数据。
    • 存储表(Mem-table):内存表是内存驻留的数据结构。 提交日志后,数据将被写入内存表。 有时,对于单列系列,将有多个内容表。
    • SSTable:当内容达到阈值时,它是从内存表刷新数据的磁盘文件。
    • 布鲁姆过滤器(Bloom filter):这些只是快速,非确定性的,用于测试元素是否是集合成员的算法。 它是一种特殊的缓存。 每次查询后都会访问Bloom过滤器。

    3、使用场景 

    特征

    • 数据写入操作密集
    • 数据修改操作很少
    • 通过主键查询
    • 需要对数据进行分区存储

    场景举例

    • 存储日志型数据
    • 类似物联网的海量数据
    • 对数据进行跟踪官网

    官网

    二、安装

    docker pull cassandra
    docker run -d -p 9042:9042  --name cassandra cassandra:latest

    进入cassandra的命令行 

    1. docker exec -it cassandra bash
    2. cqlsh

    cassandra数据存放位置共有三处地方:

    data目录:

            用于存储真正的数据文件,即SSTable文件。如果服务器有多个磁盘,可以指定多个目录,每一个目录都在不同的磁盘中。这样Cassandra就可以利用更多的硬盘空间。在data目录下,Cassandra 会将每一个 Keyspace 中的数据存储在不同的文件目录下,并且 Keyspace 文件目录的名称与 Keyspace 名称相同。

    commitlog目录:

            用于存储未写入SSTable中的数据,每次Cassandra系统中有数据写入,都会先将数据记录在该日志文件中,以保证Cassandra在任何情况下宕机都不会丢失数据。如果服务器有足够多的磁盘,可以将本目录设置在一个与data目录和cache目录不同的磁盘中,以提升读写性能。

    cache目录:

            用于存储系统中的缓存数据

    配置文件cassandra.yaml进行修改配置。

     cassandra.yaml说明查看

    三、基本概念

    1、数据模型

            Cassandra的数据模型与常见的关系型数据库的数据模型有很大的不同

    列(Column)

    列是Cassandra的基本数据结构单元,具有三个值:名称,值、时间戳

     列(Column)不需要预先定义,只需要在KeySpace里定义列族,然后就可以开始写数据了。

    列族

            列族相当于关系数据库的表(Table),是包含了多行(Row)的容器。

    可以理解为Java结构 Map>,如图:

     

     1)Row key
            ColumnFamily 中的每一行都用Row Key(行键)来标识,这个相当于关系数据库表中的主键,并且总是被索引的。

    2)主键
    Cassandra可以使用PRIMARY KEY 关键字创建主键,主键分为2种

    1.单键(一个字段) 2.组合键(多个字段组成)

    列族具有以下属性 -

    • keys_cached - 它表示每个SSTable保持缓存的位置数。
    • rows_cached - 它表示其整个内容将在内存中缓存的行数。
    • preload_row_cache -它指定是否要预先填充行缓存。

    KeySpace

            Cassandra的键空间(KeySpace)相当于数据库,我们创建一个键空间就是创建了一个数据库。键空间包含一个或多个列族(Column Family)

    注意:一般将有关联的数据放到同一个 KeySpace 下面,建空间 (KeySpace) 创建的时候可以指定一些属性:副本因子,副本策略,Durable_writes(是否启用 CommitLog 机制)

    副本因子:

            副本就是把数据存储到多个节点,来提高容错性。副本因子决定数据有几份副本。例如:副本因子为1表示每一行只有一个副,。副本因子为2表示每一行有两个副本,每个副本位于不同的节点上。在实际应用中为了避免单点故障,会配置为3以上。

            注意:副本没有主从之分。可以为每个数据中心定义副本因子。副本策略设置应大于1,但是不能超过集群中的节点数。

    副本策略:

            描述的是副本放在集群中的策略,目前有2种策略,内容如下:

    Durable_writes:

            是否启用 CommitLog 机制,默认为true

    节点(Node)

    存储数据的机器

    集群(Cluster)

            Cassandra数据库是为跨越多条主机共同工作,对用户呈现为一个整体的分布式系统设计的。Cassandra最外层容器被称为群集。Cassandra将集群中的节点组织成一个环(ring),然后把数据分配到集群中的节点(Node)上。

    2、数据类型

    基础类型

    集合类型 

     

     Map: 

            1、集合的每一项最大是64K。 2、保持集合内的数据不要太大,免得Cassandra 查询延时过长,Cassandra 查询时会读出整个集合内的数据,集合在内部不会进行分页,集合的目的是存储小量数据。 3、不要向集合插入大于64K的数据,否则只有查询到前64K数据,其它部分会丢失。

    自定义数据类型

    Cqlsh为用户提供了创建自己的数据类型的功能。 下面给出了处理用户定义的数据类型时使用的命令。

    • CREATE TYPE - 创建用户定义的数据类型。
    • ALTER TYPE - 修改用户定义的数据类型。
    • DROP TYPE - 删除用户定义的数据类型。
    • DESCRIBE TYPE - 描述用户定义的数据类型。
    • DESCRIBE TYPES - 描述用户定义的数据类型。

    四、操作

    操作类型:

    1.客户端操作

    1. docker exec -it my_cassandra /bin/bash
    2. cd bin
    3. cqlsh

    cqlsh的基本命令 

    选项使用/作用
    help此命令用于显示有关CQLsh命令选项的帮助主题。
    version它用于查看您正在使用的CQLsh的版本。
    color它用于彩色输出。
    debug它显示其他调试信息。
    execute它用于引导shell接受并执行CQL命令。
    show显示当前会话详情

    help 可以查看cqlsh 支持的命令

     Describe cluster 提供有关集群的信息

     

    Describe Keyspaces:显示当前Cassandra里的所有键空间 

     Describe tables 列出键空间的所有表

    CQL-查询语言

    数据定义命令

    Keyspace

    1、创建

    1. 语法:
    2. CREATE KEYSPACE <identifier> WITH <properties>
    3. 具体语法:
    4. Create keyspace KeyspaceName with replicaton={'class':strategy name,
    5. 'replication_factor': No of replications on different nodes}
    • KeyspaceName 代表键空间的名字
    • strategy name 代表副本放置策略,内容包括:简单策略、网络拓扑策略,选择其中的一个。
    • No of replications on different nodes 代表 复制因子,放置在不同节点上的数据的副本数。

    新建: 

    CREATE KEYSPACE company WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 3};

    CREATE KEYSPACE test_keyspace WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'datacenter1' : 3 } AND DURABLE_WRITES = false;

    验证: 

     DESCRIBE keyspaces ;

    DESCRIBE company ;

    2、使用键空间

    USE <identifier>

    USE company;

    3、修改键空间

    1. 语法:
    2. ALTER KEYSPACE <identifier> WITH <properties>
    3. 或者 -
    4. ALTER KEYSPACE "KeySpace Name" WITH replication = {'class': 'Strategy name',
    5. 'replication_factor' : 'No.Of replicas'};
    6. 又或者 -
    7. Alter Keyspace KeyspaceName with replication={'class':'StrategyName',
    8. 'replication_factor': no of replications on different nodes}
    9. with DURABLE_WRITES=true/false

    注意:

    • Keyspace Name: Cassandra中的键名称不能更改。
    • Strategy Name: 可以通过使用新的策略名称来更改战略名称。
    • Replication Factor : 可以通过使用新的复制因子来更改复制因子。
    • DURABLE_WRITES:可以通过指定其值true / false来更改。 默认情况下为true。 如果设置为false,则不会将更新写入提交日志,反之亦然。

    修改: 

    alter KEYSPACE company WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};

    验证:

    DESCRIBE company ;

    4、删除键空间

    DROP KEYSPACE <identifier>

    DROP KEYSPACE company;

    表操作

    注意:操作前,先把键空间company键空间创建,并使用company键空间.

    CREATE KEYSPACE company WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};
    use company;

    1、查看所有的表

    DESCRIBE TABLES;

    2、创建表

    1. CREATE (TABLE | COLUMNFAMILY) <tablename>
    2. ('' , '')
    3. (WITH <option> AND <option>)
    1. CREATE TABLE t_user(
    2. id int PRIMARY KEY,
    3. name text,
    4. age int,
    5. gender tinyint,
    6. address text ,
    7. interest set<text>,
    8. phone list<text>,
    9. education map<text, text>
    10. );

    验证 

    DESCRIBE TABLE t_user;

     主键有两种类型:

    • 单个主键:对单个主键使用以下语法。
      Primary key (ColumnName)
      
    • 复合主键:对复合主键可使用以下语法。
      1. Primary key(ColumnName1,ColumnName2 . . .)
      2. -
      3. Primary key((key_part_one,key_part_two),ColumnName2 . . .)
      4. key_part_one:称作Partition Key,Cassandra会对其做一个hash计算,决定放在哪个节点。
      5. key_part_two:CLUSTERING KEY

    3、修改表结构

    语法,可以添加列,删除列

    1. 添加一列:
    2. ALTER (TABLE | COLUMNFAMILY) <tablename> <instruction>
    3. 删除一列:
    4. ALTER table name DROP name;

    ALTER TABLE t_user ADD email text;
    ALTER table t_user DROP  email;

    4、删除表

    DROP TABLE <tablename>

    5、清空表

    TRUNCATE <tablename>

    索引操作

    1、普通列创建索引

    CREATE INDEX <identifier> ON <tablename>

    创建索引的规则

    • 由于主键已编入索引,因此无法在主键上创建索引。
    • 在Cassandra中,不支持集合索引。
    • 没有对列进行索引,Cassandra无法过滤该列,除非它是主键。

    CREATE INDEX sname ON t_user(name);

    索引原理:

            Cassandra自动新创建了一张表格,同时将原始表格之中的索引字段作为新索引表的Primary Key!并且存储的值为原始数据的Primary Key.

    2、集合列创建索引

    CREATE INDEX ON t_user(interest);                 -- set集合添加索引
    CREATE INDEX mymap ON t_user(KEYS(education));          -- map结合添加索引

    3、删除索引

    DROP INDEX

    CRUD操作

     数据操作指令

    查询指令 

    1、插入数据

    1. INSERT INTO <tablename>
    2. (<column1 name>, <column2 name>....)
    3. VALUES (<value1>, <value2>....)
    4. USING <option>

    INSERT INTO t_user(id, address, age, education, gender, interest, name, phone)
    VALUES (1,'dizhi',12,{'code':'12'},1,{'yestouu@gmail.com'},'zs',['123456','1234']);
    INSERT INTO t_user(id, address, age, education, gender, interest, name, phone)
    VALUES (2,'dizhi',12,{'code':'12'},1,{'yestouu@gmail.com'},'zs',['123456','1234']);
    INSERT INTO t_user(id, address, age, education, gender, interest, name, phone)
    VALUES (3,'dizhi',12,{'code':'12'},1,{'yestouu@gmail.com'},'zs',['123456','1234']);

    2、更新数据

    1. UPDATE <tablename>
    2. SET <column name> = <new value>
    3. <column name> = <value>....
    4. WHERE <condition>
    5. 又或者 -
    6. Update KeyspaceName.TableName
    7. Set ColumnName1=new Column1Value,
    8. ColumnName2=new Column2Value,
    9. ColumnName3=new Column3Value,
    10. .
    11. .
    12. .
    13. Where ColumnName=ColumnValue

    update t_user set age=2,phone=['1'] where id =1;

    #更新set类型数据

    update t_user set interest= interest + {'aa'} where id = 1;

    update t_user set interest = interest - {'aa'} where id = 1;

    update t_user set interest = {} WHERE id = 1;

    #更新list类型数据

    update t_user set phone = [ '030-55555555' ] + phone where id= 1;

    update t_user set phone = phone + [ '040-33333333' ] where id= 1;

    update t_user set phone[2] = '050-22222222' where id= 1;

    update t_user set phone = phone - ['020-66666666'] where id= 1;

    update t_user set phone =[] where id= 1;
    #更新map类型数据

    update t_user set education={'e': 'f'} where id= 1;

    #UPDATE命令设置指定元素的value

    update t_user set education['e']='g' where id= 1;

    update t_user set education = education + {'a':'b','c':'d'} where id= 1;

    update t_user set education=education - {'a','c'} WHERE id = 1;
    UPDATE t_user SET education={} WHERE id = 1;

    3、删除数据

    DELETE FROM <identifier> WHERE <condition>;
    

    delete from t_user where id=1;

    #删除某个字段

    delete interest FROM t_user WHERE id= 1;

    4、查询数据

    使用 SELECT 、WHERE、LIKE、GROUP BY 、ORDER BY等关键词

    SELECT FROM
    SELECT FROM

    WHERE ;

    查询所有数据

    select * from t_user;

    根据主键查询

    select * from t_user where id =1;

    查询时使用索引

    注意事项:

    • Primary Key 只能用 = 号查询
    • 第二主键 支持= > < >= <=
    • 索引列 只支持 = 号
    • 非索引非主键字段过滤可以使用ALLOW FILTERING
    1. create table student (
    2. key_one int,
    3. key_two int,
    4. name text,
    5. age  int,
    6. PRIMARY KEY(key_one, key_two)
    7. );
    8. create INDEX tage ON student (age);

    key_one 是第一主键,key_two是第二主键,age是索引列,name是普通列

    1. insert into student(key_one,key_two,name,age) values(1,2,'a',2);
    2. insert into student(key_one,key_two,name,age) values(2,3,'b',2);
    3. insert into student(key_one,key_two,name,age) values(3,4,'c',2);
    4. insert into student(key_one,key_two,name,age) values(4,5,'d',2);

      

    第一主键 只能用=号查询

    select * from student where key_one=1;

     select * from student where key_one>1;

    如果需要完成这个查询,可以使用 ALLOW FILTERING

    select * from student where key_one>1 ALLOW FILTERING;

     

     注意:加上ALLOW FILTERING 后确实可以查询出数据,但是不建议这么做

     第二主键 支持 = 、>、 <、 >= 、 <=

    key_two是第二主键,不要单独对key_two 进行 查询,

    select * from student where key_two = 2;

     如果需要完成这个查询,可以使用 ALLOW FILTERING

    select * from student where key_two = 2 ALLOW FILTERING;

     注意:加上ALLOW FILTERING 后确实可以查询出数据,但是不建议这么做

    正确用法: 

    select * from student where key_one=1 and key_two = 2 ;

     索引列 只支持=号

    select * from student where age = 2;

    普通列,非索引非主键字段

    普通列,在查询时需要使用ALLOW FILTERING

    select * from student where key_one =1 and name='a';

     select * from student where key_one =1 and name='a' ALLOW FILTERING;

     集合列

    ALTER TABLE student ADD email set;

    ALTER TABLE student ADD phone list;

    ALTER TABLE student ADD education map;

    create INDEX temail ON student (email);
    create INDEX tphone ON student (phone);
    create INDEX teducation ON student (education);

    insert into  student(key_one,key_two,name,age,email,phone,education) values(6,7,'d',2,{'1234'},['1'],{'info':'张三'});
    insert into  student(key_one,key_two,name,age,email,phone,education) values(7,8,'d',2,{'1234'},['1'],{'info':'张四'});

    使用where子句的CONTAINS条件按照给定的值进行过滤。

    select * from student where email CONTAINS '1234';  -- 查询set集合

    select * from student where education CONTAINS key  'info' allow filtering; --查询map集合的key值
    select * from student where education CONTAINS '张四';  --查询map的value值

     ALLOW FILTERING

            ALLOW FILTERING是一种非常消耗计算机资源的查询方式。 如果表包含例如100万行,并且其中95%具有满足查询条件的值,则查询仍然相对有效,这时应该使用ALLOW FILTERING。

            如果表包含100万行,并且只有2行包含满足查询条件值,则查询效率极低。Cassandra将无需加载999,998行。如果经常使用查询,则最好在列上添加索引。

            ALLOW FILTERING在表数据量小的时候没有什么问题,但是数据量过大就会使查询变得缓慢。

    查询时排序

            cassandra也是支持排序的,order by。 排序也是有条件的

    1.必须有第一主键的=号查询

            cassandra的第一主键是决定记录分布在哪台机器上,cassandra只支持单台机器上的记录排序。

    2.只能根据第二、三、四…主键进行有序的,相同的排序。

     3.不能有索引查询

        cassandra的任何查询,最后的结果都是有序的,内部就是这样存储的。

    select * from student where key_one = 1 order by key_two;

    select * from student where key_one = 1 and age =2 order by  key_two; --错误,不能有索引查询

    分页查询

            使用limit 关键字来限制查询结果的条数 进行分页

    select * from student where key_one = 1 order by  key_two limit 1; 

    批量操作

            多次更新操作合并为一次请求,减少客户端和服务端的网络交互。 batch中同一个partition key的操作具有隔离性.

    使用BATCH,可以同时执行多个修改语句(插入,更新,删除)

    1. BEGIN BATCH
    2. <insert-stmt>/ <update-stmt>/ <delete-stmt>
    3. APPLY BATCH

     

    1. BEGIN BATCH
    2. INSERT INTO t_user(id, address, age, education, gender, interest, name, phone) VALUES (5,'dizhi',12,{'code':'12'},1,{'yestouu@gmail.com'},'zs',['123456','1234']);
    3. UPDATE t_user set age = 11 where id= 1;
    4. DELETE FROM t_user WHERE id=2;
    5. APPLY BATCH;

     2.JAVA操作

    1. org.springframework.boot
    2. spring-boot-starter-data-cassandra
    1. # 应用名称
    2. spring:
    3. application:
    4. name: spring-lean-cassandra
    5. data:
    6. cassandra:
    7. contact-points: 192.168.56.1
    8. port: 9042
    9. local-datacenter: datacenter1
    10. session-name: cassandraCluster
    11. username:
    12. password:
    13. keyspace-name: company
    14. # 应用服务 WEB 访问端口
    15. server:
    16. port: 9088

    手动创建 keyspace和表。

    1. CREATE TABLE person
    2. (
    3. id int,
    4. name text,
    5. name_cn text,
    6. age int,
    7. PRIMARY KEY (id)
    8. );
    9. CREATE TABLE city
    10. (
    11. id int,
    12. name text,
    13. persons list<text>,
    14. PRIMARY KEY (id)
    15. );
    16. CREATE TABLE t_user
    17. (
    18. id int,
    19. name text,
    20. age int,
    21. books list<text>,
    22. PRIMARY KEY (id)
    23. );
    24. CREATE TABLE testdb (
    25. key_one text,
    26. key_two text,
    27. value double,
    28. PRIMARY KEY (key_one,key_two )
    29. );

    1. import lombok.Data;
    2. import org.springframework.data.cassandra.core.mapping.*;
    3. import java.util.List;
    4. @Data
    5. @Table
    6. public class City {
    7. @PrimaryKey
    8. private int id;
    9. private String name;
    10. private List persons;
    11. }
    12. import lombok.Data;
    13. import org.springframework.data.cassandra.core.mapping.Column;
    14. import org.springframework.data.cassandra.core.mapping.PrimaryKey;
    15. import org.springframework.data.cassandra.core.mapping.Table;
    16. @Data
    17. @Table
    18. public class Person {
    19. @PrimaryKey
    20. private Integer id;
    21. private String name;
    22. @Column(value = "name_cn")
    23. private String nameCn;
    24. private Integer age;
    25. }
    26. import lombok.Data;
    27. import org.springframework.data.cassandra.core.mapping.PrimaryKey;
    28. import org.springframework.data.cassandra.core.mapping.Table;
    29. import java.io.Serializable;
    30. import java.util.List;
    31. @Data
    32. @Table("t_user")
    33. public class User implements Serializable {
    34. @PrimaryKey
    35. private int id;
    36. private String name;
    37. private int age;
    38. private List books;
    39. }
    40. import lombok.Data;
    41. import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
    42. import org.springframework.data.cassandra.core.mapping.Column;
    43. import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
    44. import org.springframework.data.cassandra.core.mapping.Table;
    45. @Data
    46. @Table("testdb")
    47. public class TestDb {
    48. @PrimaryKeyColumn(value = "key_one",type = PrimaryKeyType.PARTITIONED)
    49. private String keyOne;
    50. @PrimaryKeyColumn(value = "key_two",type = PrimaryKeyType.CLUSTERED)
    51. private String keyTwo;
    52. @Column("value")
    53. private double value;
    54. }
    1. import org.springframework.boot.SpringApplication;
    2. import org.springframework.boot.autoconfigure.SpringBootApplication;
    3. import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
    4. @EnableCassandraRepositories
    5. @SpringBootApplication
    6. public class SpringLeanCassandraApplication {
    7. public static void main(String[] args) {
    8. SpringApplication.run(SpringLeanCassandraApplication.class, args);
    9. }
    10. }

     第一种方式:集成CassandraRepository对象。

    1. import com.lean.cassandra.entity.City;
    2. import org.springframework.data.cassandra.repository.CassandraRepository;
    3. public interface CityRepository extends CassandraRepository {
    4. }
    5. import com.lean.cassandra.entity.Person;
    6. import org.springframework.data.cassandra.repository.AllowFiltering;
    7. import org.springframework.data.cassandra.repository.CassandraRepository;
    8. public interface PersonRepository extends CassandraRepository {
    9. /**
    10. * 根据名字查询
    11. *
    12. * @param name 名字
    13. * @return Person
    14. */
    15. @AllowFiltering
    16. Person findByName(String name);
    17. }

    第二种方式:使用CassandraTemplate进行操作。

    1. import com.lean.cassandra.entity.User;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.data.cassandra.core.CassandraTemplate;
    4. import org.springframework.data.cassandra.core.query.Query;
    5. import org.springframework.stereotype.Service;
    6. import java.io.Serializable;
    7. import java.util.List;
    8. @Service
    9. public class UserService {
    10. @Autowired
    11. private CassandraTemplate cassandraTemplate;
    12. public void saveUser(User user){
    13. cassandraTemplate.insert(user);
    14. }
    15. public void batchSaveUser(List userList){
    16. cassandraTemplate.batchOps().insert(userList);
    17. }
    18. public void updateUser(User user){
    19. cassandraTemplate.update(user);
    20. }
    21. public User getById(Serializable id) {
    22. return cassandraTemplate.selectOneById(id, User.class);
    23. }
    24. public User getObj(Query query) {
    25. return cassandraTemplate.selectOne(query, User.class);
    26. }
    27. public List listObjs(Query query) {
    28. return cassandraTemplate.select(query, User.class);
    29. }
    30. }
    1. package com.lean.cassandra.service;
    2. import com.lean.cassandra.entity.TestDb;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.data.cassandra.core.CassandraTemplate;
    5. import org.springframework.data.cassandra.core.query.Criteria;
    6. import org.springframework.data.cassandra.core.query.Query;
    7. import org.springframework.stereotype.Service;
    8. import java.util.List;
    9. @Service
    10. public class TestDbService {
    11. @Autowired
    12. private CassandraTemplate cassandraTemplate;
    13. public TestDb save(TestDb testDb) {
    14. return cassandraTemplate.insert(testDb);
    15. }
    16. public List query(TestDb testDb) {
    17. return cassandraTemplate.select("select * from testdb where key_one = '"+testDb.getKeyOne()+"';", TestDb.class);
    18. }
    19. public boolean delete(TestDb testDb) {
    20. return cassandraTemplate.delete(Query.query(Criteria.where("key_one").is(testDb.getKeyOne())).and(Criteria.where("key_two").lte(testDb.getKeyTwo())), TestDb.class);
    21. }
    22. }

    测试:

    第一种:

    1. import com.lean.cassandra.entity.City;
    2. import com.lean.cassandra.entity.Person;
    3. import com.lean.cassandra.repository.CityRepository;
    4. import org.junit.jupiter.api.Test;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. import java.util.LinkedList;
    8. import java.util.List;
    9. @SpringBootTest
    10. public class CityRepositoryTest {
    11. @Autowired
    12. private CityRepository cityRepository;
    13. @Test
    14. public void save() {
    15. List list = new LinkedList<>();
    16. for (int i = 0; i < 20; i++) {
    17. Person person = new Person();
    18. person.setId(i + 1);
    19. person.setAge(18 + i);
    20. person.setName("test" + (i + 1));
    21. person.setNameCn("测试" + (i + 1));
    22. list.add(person.toString());
    23. }
    24. City city = new City();
    25. city.setId(1);
    26. city.setName("深圳");
    27. city.setPersons(list);
    28. cityRepository.save(city);
    29. }
    30. }

    1. package com.lean.cassandra;
    2. import com.lean.cassandra.entity.Person;
    3. import com.lean.cassandra.repository.PersonRepository;
    4. import org.junit.jupiter.api.Test;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. import org.springframework.data.cassandra.core.query.CassandraPageRequest;
    8. import org.springframework.data.domain.Pageable;
    9. import java.util.LinkedList;
    10. import java.util.List;
    11. @SpringBootTest
    12. public class PersonRepositoryTest {
    13. @Autowired
    14. private PersonRepository repository;
    15. @Test
    16. public void save() {
    17. Person person = new Person();
    18. person.setId(1);
    19. person.setName("xxb");
    20. person.setAge(18);
    21. repository.save(person);
    22. }
    23. @Test
    24. public void saveAll() {
    25. List list = new LinkedList<>();
    26. for (int i = 1; i < 20; i++) {
    27. Person person = new Person();
    28. person.setId(i + 1);
    29. person.setAge(18 + i);
    30. person.setName("test" + (i + 1));
    31. person.setNameCn("测试" + (i + 1));
    32. list.add(person);
    33. }
    34. repository.saveAll(list);
    35. }
    36. @Test
    37. public void findById() {
    38. Person person = repository.findById(1).orElse(null);
    39. System.out.println(person);
    40. }
    41. @Test
    42. public void findByName() {
    43. Person person = repository.findByName("xxb");
    44. System.out.println(person);
    45. }
    46. @Test
    47. public void update() {
    48. Person person = repository.findById(1).orElse(null);
    49. person.setAge(20);
    50. repository.save(person);
    51. System.out.println(person);
    52. }
    53. @Test
    54. public void all() {
    55. List personList = repository.findAll();
    56. System.out.println(personList);
    57. }
    58. @Test
    59. public void count() {
    60. long count = repository.count();
    61. System.out.println(count);
    62. }
    63. @Test
    64. public void delete() {
    65. repository.deleteById(1);
    66. Person person = repository.findById(1).orElse(null);
    67. System.out.println(person);
    68. }
    69. @Test
    70. public void deleteAll() {
    71. repository.deleteAll();
    72. long count = repository.count();
    73. System.out.println(count);
    74. }
    75. @Test
    76. public void page() {
    77. Pageable pageable = CassandraPageRequest.of(0, 5);
    78. List list = repository.findAll(pageable).getContent();
    79. System.out.println(list);
    80. }
    81. }

     第二种:

    1. package com.lean.cassandra;
    2. import com.alibaba.fastjson.JSON;
    3. import com.datastax.oss.driver.api.querybuilder.QueryBuilder;
    4. import com.google.common.collect.Lists;
    5. import com.lean.cassandra.entity.User;
    6. import com.lean.cassandra.service.UserService;
    7. import org.junit.Test;
    8. import org.junit.runner.RunWith;
    9. import org.springframework.beans.factory.annotation.Autowired;
    10. import org.springframework.boot.test.context.SpringBootTest;
    11. import org.springframework.data.cassandra.core.query.Query;
    12. import org.springframework.test.context.junit4.SpringRunner;
    13. import java.util.ArrayList;
    14. import java.util.List;
    15. @RunWith(SpringRunner.class)
    16. @SpringBootTest
    17. public class UserServiceTest {
    18. @Autowired
    19. private UserService userService;
    20. @Test
    21. public void saveUser() {
    22. User user = new User();
    23. user.setId(1);
    24. user.setName("aa");
    25. user.setAge(10);
    26. user.setBooks(Lists.newArrayList());
    27. userService.saveUser(user);
    28. }
    29. @Test
    30. public void batchSaveUser() {
    31. List userList = new ArrayList<>();
    32. for (int i = 2; i < 100; i++) {
    33. User user = new User();
    34. user.setId(0);
    35. user.setName("aa");
    36. user.setAge(10);
    37. user.setBooks(Lists.newArrayList());
    38. userList.add(user);
    39. }
    40. userService.batchSaveUser(userList);
    41. }
    42. @Test
    43. public void updateUser() {
    44. User user = new User();
    45. user.setId(1);
    46. user.setName("dd");
    47. user.setAge(10);
    48. user.setBooks(Lists.newArrayList());
    49. userService.updateUser(user);
    50. }
    51. @Test
    52. public void getById() {
    53. Integer id = 1;
    54. User user = userService.getById(id);
    55. System.out.println(JSON.toJSONString(user));
    56. }
    57. @Test
    58. public void getUserDetail() {
    59. Query query = Query.empty();
    60. // query = query.withAllowFiltering();
    61. User user = userService.getObj(query);
    62. System.out.println(JSON.toJSONString(user));
    63. }
    64. @Test
    65. public void findUserList() {
    66. Query query = Query.empty();
    67. // query = query.withAllowFiltering();
    68. List userList = userService.listObjs(query);
    69. System.out.println(JSON.toJSONString(userList));
    70. }
    71. }

     

    1. package com.lean.cassandra;
    2. import com.alibaba.fastjson.JSON;
    3. import com.lean.cassandra.entity.TestDb;
    4. import com.lean.cassandra.service.TestDbService;
    5. import org.junit.Test;
    6. import org.junit.runner.RunWith;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.boot.test.context.SpringBootTest;
    9. import org.springframework.test.context.junit4.SpringRunner;
    10. import java.util.List;
    11. @RunWith(SpringRunner.class)
    12. @SpringBootTest
    13. public class TestDbTest {
    14. @Autowired
    15. private TestDbService testDbService;
    16. @Test
    17. public void save() {
    18. for (int i = 0; i < 100; i++) {
    19. TestDb testDb=new TestDb();
    20. if(i%2==0){
    21. testDb.setKeyOne("1");
    22. }else {
    23. testDb.setKeyOne("2");
    24. }
    25. testDb.setKeyTwo((i+2)+"");
    26. testDb.setValue(1.0D);
    27. testDbService.save(testDb);
    28. }
    29. }
    30. @Test
    31. public void query() {
    32. TestDb testDb=new TestDb();
    33. testDb.setKeyOne("1");
    34. List query = testDbService.query(testDb);
    35. System.out.println(JSON.toJSONString(query));
    36. }
    37. @Test
    38. public void delete() {
    39. TestDb testDb=new TestDb();
    40. testDb.setKeyOne("1");
    41. testDb.setKeyTwo("2");
    42. testDbService.delete(testDb);
    43. }
    44. }

    官方网址 

    cassandra可视化客户端​​​​​​​

    分布式算法实用指南

     Cassandra数据库

  • 相关阅读:
    真实场景下的安全专家各项技能详解
    蚂蚁金服Java研发岗二面:说说HashMap 中的容量与扩容实现
    经典Ubuntu20.04版本U盘安装双系统教程
    【SQL性能优化】索引的原理:我们为什么用B+树来做索引?
    NFT Insider #63:The Sandbox与时代杂志达成合作,YGG成立西班牙subDAO
    关于 WordPress 你了解多少?
    【夯实算法基础】 并查集
    每日学习总结20240313
    docker 数据持久化
    mysql给所有数据库表加字段
  • 原文地址:https://blog.csdn.net/weixin_43549578/article/details/127874917