Spring整合Cassandra的简单使用

1,924 阅读2分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

之前写了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. 输出结果

    1061277-20161207205804929-13205491