Spring整合Cassandra的简单使用

 2023-02-18
原文作者:我是大明哥 原文地址:https://juejin.cn/post/7025921041775984647

「」

之前写了JAVA操作cassandra驱动包,现在来看看spring-data对cassandra的支持。这里是spring-data-cassandra的官方文档:docs.spring.io/spring-data… 这个目录下还有api、版本日志等:docs.spring.io/spring-data…

  1. 引入jar包
    <dependency>
       <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-cassandra</artifactId>
        <version>1.5.0.M1</version>
    </dependency>
  1. 定义bean
    import org.springframework.data.cassandra.mapping.Column;
    import org.springframework.data.cassandra.mapping.PrimaryKey;
    import org.springframework.data.cassandra.mapping.Table;
    
    @Table
    public class Person
    {
        // 主键
        @PrimaryKey
        private String id;
    
        // 列名 与数据库列名一致时可不加
        @Column(value = "name")
        private String name;
    
        private int age;
    
        // 支持构造函数
        public Person(String id, String name, int age)
        {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public String getId()
        {
            return id;
        }
    
        public void setId(String id)
        {
            this.id = id;
        }
    
        public String getName()
        {
            return name;
        }
    
        public void setName(String name)
        {
            this.name = name;
        }
    
        public int getAge()
        {
            return age;
        }
    
        public void setAge(int age)
        {
            this.age = age;
        }
    
        @Override
        public String toString()
        {
            return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
        }
    
    }
  1. 对应的CQL建表语句
    CREATE TABLE mydb.person (
        id text PRIMARY KEY,
        age int,
        name text
    )

可以看出和JPA的注解很类似,不同的是cassandra主键用的是@PrimaryKey,而且允许使用构造函数。如果存在复合主键,则要先映射一个主键的实体类,再映射一个包含这个主键的实体类。

例如:

    import org.springframework.cassandra.core.Ordering;
    import org.springframework.cassandra.core.PrimaryKeyType;
    import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
    import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
    
    @PrimaryKeyClass
    public class Person2Key
    {
    
        // 分区键
        @PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
        private String id;
    
        // 集群键
        @PrimaryKeyColumn(name = "name", ordinal = 1, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING)
        private String name;
    
        public String getId()
        {
            return id;
        }
    
        public void setId(String id)
        {
            this.id = id;
        }
    
        public String getName()
        {
            return name;
        }
    
        public void setName(String name)
        {
            this.name = name;
        }
    
        @Override
        public String toString()
        {
            return "Person2Key [id=" + id + ", name=" + name + "]";
        }
    
    }
    import org.springframework.data.cassandra.mapping.PrimaryKey;
    import org.springframework.data.cassandra.mapping.Table;
    
    @Table(value = "person2")
    public class Person2
    {
        @PrimaryKey
        private Person2Key pKey;
    
        private int age;
    
        public Person2Key getpKey()
        {
            return pKey;
        }
    
        public void setpKey(Person2Key pKey)
        {
            this.pKey = pKey;
        }
    
        public int getAge()
        {
            return age;
        }
    
        public void setAge(int age)
        {
            this.age = age;
        }
    
        @Override
        public String toString()
        {
            return "Person2 [pKey=" + pKey + ", age=" + age + "]";
        }
    
    }

对应的CQL建表语句

    CREATE TABLE mydb.person2 (
        id text,
        name text,
        age int,
        PRIMARY KEY (id, name)
    ) WITH CLUSTERING ORDER BY (name DESC)

其中的WITH CLUSTERING ORDER BY (name DESC) 对应主键类里的ordering = Ordering.DESCENDING,按照name降序存储,只有集群键才能在建表时设置降序存储。

  1. 定义spring-data接口
    import java.util.List;
    
    import org.springframework.data.cassandra.repository.Query;
    import org.springframework.data.repository.CrudRepository;
    import org.springframework.stereotype.Repository;
    
    import com.my.domin.pojo.Person2;
    
    @Repository
    public interface PersonRepository extends CrudRepository<Person2, String>
    {
        @Query("select * from Person2 where id= ?1 and name= ?2")
        List<Person2> findByIdAndName(String id, String name);
    }

这里面实现了一组CURD方法,如果要写一些条件查询的话可以参考

    @Query("select * from Person where id= ?1 and name= ?2 ALLOW FILTERING")
     List<Person> findByIdAndName(String id, String name);

spring-data-cassandra文档里还提到一个分页的仓库接口类PagingAndSortingRepository,这个继承自CrudRepository,而且提供了2个分页方法。

  1. 测试方法:
    import java.util.Iterator;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.cassandra.core.CassandraOperations;
    import org.springframework.stereotype.Service;
    
    import com.datastax.driver.core.querybuilder.QueryBuilder;
    import com.datastax.driver.core.querybuilder.Select;
    import com.my.domin.pojo.Person;
    import com.my.repository.PersonRepository;
    import com.my.service.PersonService;
    
    @Service
    public class PersonServiceImpl implements PersonService
    {
        @Autowired
        private PersonRepository personRepository;
    
        @Autowired
        private CassandraOperations cassandraOperations;
    
        @Override
        public void test()
        {
            //通过Repository查询
            Iterable<Person> iterable = personRepository.findAll();
            Iterator<Person> it = iterable.iterator();
            System.out.println("==>findAll:");
            while (it.hasNext())
            {
                Person p = it.next();
                System.out.println(p.toString());
            }
            
            //通过Repository 自定义查询查询
            List<Person> list = personRepository.findByIdAndName("1", "one");
            System.out.println("==>findByIdAndName:");
            for (Person person : list)
            {
                System.out.println(person.toString());
            }
            //通过cassandraOperations查询
            Select select = QueryBuilder.select().from("person");
            select.where(QueryBuilder.eq("id", "1"));
            Person person = cassandraOperations.selectOne(select, Person.class);
            System.out.println("==>cassandraOperations:");
            System.out.println(person.toString());
    
        }
    
    }
  1. 输出结果

    202301012110447361.png