以前寫了JAVA操做cassandra驅動包,如今來看看spring-data對cassandra的支持。這裏是spring-data-cassandra的官方文檔:http://docs.spring.io/spring-data/cassandra/docs/1.5.0.M1/reference/html/ html
這個目錄下還有api、版本日誌等:http://docs.spring.io/spring-data/cassandra/docs/1.5.0.M1/java
<!-- 這裏對應的是cassandra3.0以後的版本 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-cassandra</artifactId> <version>1.5.0.M1</version> </dependency>
package com.my.domin.pojo; 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 + "]"; } }
對應的CQL建表語句spring
CREATE TABLE mydb.person ( id text PRIMARY KEY, age int, name text )
能夠看出和JPA的註解很相似,不一樣的是cassandra主鍵用的是@PrimaryKey,並且容許使用構造函數。
若是存在複合主鍵,則要先映射一個主鍵的實體類,再映射一個包含這個主鍵的實體類數據庫
package com.my.domin.pojo; 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 + "]"; } }
package com.my.domin.pojo; 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建表語句express
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降序存儲,只有集羣鍵才能在建表時設置降序存儲。
其實還有更加複雜的複合分區鍵、複合集羣鍵組合成的主鍵,看懂了上面應該就能觸類旁通了,並且用的很少,這裏就不寫了。apache
package com.my.repository; 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); }
咱們能夠看看繼承的CrudRepository這個倉庫接口類api
/* * Copyright 2008-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.data.repository; import java.io.Serializable; /** * Interface for generic CRUD operations on a repository for a specific type. * * @author Oliver Gierke * @author Eberhard Wolff */ @NoRepositoryBean public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { /** * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the * entity instance completely. * * @param entity * @return the saved entity */ <S extends T> S save(S entity); /** * Saves all given entities. * * @param entities * @return the saved entities * @throws IllegalArgumentException in case the given entity is {@literal null}. */ <S extends T> Iterable<S> save(Iterable<S> entities); /** * Retrieves an entity by its id. * * @param id must not be {@literal null}. * @return the entity with the given id or {@literal null} if none found * @throws IllegalArgumentException if {@code id} is {@literal null} */ T findOne(ID id); /** * Returns whether an entity with the given id exists. * * @param id must not be {@literal null}. * @return true if an entity with the given id exists, {@literal false} otherwise * @throws IllegalArgumentException if {@code id} is {@literal null} */ boolean exists(ID id); /** * Returns all instances of the type. * * @return all entities */ Iterable<T> findAll(); /** * Returns all instances of the type with the given IDs. * * @param ids * @return */ Iterable<T> findAll(Iterable<ID> ids); /** * Returns the number of entities available. * * @return the number of entities */ long count(); /** * Deletes the entity with the given id. * * @param id must not be {@literal null}. * @throws IllegalArgumentException in case the given {@code id} is {@literal null} */ void delete(ID id); /** * Deletes a given entity. * * @param entity * @throws IllegalArgumentException in case the given entity is {@literal null}. */ void delete(T entity); /** * Deletes the given entities. * * @param entities * @throws IllegalArgumentException in case the given {@link Iterable} is {@literal null}. */ void delete(Iterable<? extends T> entities); /** * Deletes all entities managed by the repository. */ void deleteAll(); }
這裏面實現了一組CURD方法,若是要寫一些條件查詢的話能夠參考session
@Query("select * from Person where id= ?1 and name= ?2 ALLOW FILTERING")
List<Person> findByIdAndName(String id, String name);
這裏要注意的是cassandra支持的查詢是有限制的,能夠參考這篇文章http://zhaoyanblog.com/archives/265.html 。3.0以後的版本改善了許多(如上面的查詢3.0如下的版本是不支持的,name爲非主鍵字段),一個是支持了非主鍵的條件查詢,一個是下降了集羣鍵的查詢限制條件,這裏最好本身在cql中測試一下。
spring-data-cassandra文檔裏還提到一個分頁的倉庫接口類PagingAndSortingRepository,這個繼承自CrudRepository,並且提供了2個分頁方法。可是通過測試是不能用的。。至少我沒有測試經過,不知道是沒有實現(比較傾向於這個,cassandra分頁的確比較麻煩),仍是本身沒有正確使用。app
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd http://www.springframework.org/schema/data/cassandra/spring-cql.xsd http://www.springframework.org/schema/data/cassandra/spring-cql-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> <!-- 引入屬性文件 --> <context:property-placeholder location="classpath:cassandra.properties" /> <!-- 自動掃描(自動注入) --> <context:component-scan base-package="com.my" /> <!-- 註解方式配置事物 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- spring-cassandra --> <cassandra:cluster contact-points="${cassandra_contactpoints}" port="${cassandra_port}" username="${cassandra_username}" password="${cassandra_password}" /> <!-- 當前使用scheam --> <cassandra:session keyspace-name="${cassandra_keyspace}" /> <!-- orm --> <cassandra:mapping /> <!-- 類型轉換 --> <cassandra:converter /> <!-- cassandra operater --> <cassandra:template id="cqlTemplate" /> <!-- spring data 接口 --> <cassandra:repositories base-package="com.my.repository" /> </beans>
這個配置文件都有註釋,沒什麼可講的,惟一要注意的是<cassandra:template id="cqlTemplate" /> ,官方文檔上寫的是<cassandra:template id="cassandraTemplate" />,通過測試官方文檔上寫的不能使用,改成上面的就行了。
其中cassandra.properties文件配置less
#cassandra數據庫鏈接
#節點ip
cassandra_contactpoints=192.168.3.89
#端口
cassandra_port=9042
#當前操做鍵空間
cassandra_keyspace=mydb
#登陸用戶名
cassandra_username=cassandra
#登陸密碼
cassandra_password=cassandra
package com.my.serviceImpl; 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()); } }
打印結果