Einführung in Spring Data Cassandra

1. Übersicht

Dieser Artikel ist eine praktische Einführung in die Arbeit mit Cassandra mit Spring Data.

Wir beginnen mit den Grundlagen, gehen die Konfigurationen und die Codierung durch und bauen schließlich ein vollständiges Spring Data Cassandra-Modul auf.

2. Maven-Abhängigkeiten

Beginnen wir mit der Definition der Abhängigkeiten in der Datei pom.xml mit Maven:

 com.datastax.cassandra cassandra-driver-core 2.1.9 

3. Konfiguration für Cassandra

Wir werden den Java-Konfigurationsstil verwenden, um die Cassandra-Integration zu konfigurieren.

3.1. Die Hauptkonfiguration

Beginnen wir mit der Hauptkonfigurationsklasse - natürlich gesteuert über die Annotation @Configuration auf Klassenebene :

@Configuration public class CassandraConfig extends AbstractCassandraConfiguration { @Override protected String getKeyspaceName() { return "testKeySpace"; } @Bean public CassandraClusterFactoryBean cluster() { CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); cluster.setContactPoints("127.0.0.1"); cluster.setPort(9142); return cluster; } @Bean public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { return new BasicCassandraMappingContext(); } }

Beachten Sie die neue Bean - BasicCassandraMappingContext - mit einer Standardimplementierung. Dies ist erforderlich, um die persistenten Entitäten zwischen ihrem Objekt und ihren persistenten Formaten zuzuordnen.

Und da die Standardimplementierung ausreichend ist, können wir sie direkt verwenden.

3.2. Cassandra-Verbindungseigenschaften

Es gibt drei obligatorische Einstellungen, die wir konfigurieren müssen, um die Verbindung für einen Cassandra-Client einzurichten.

Wir müssen den Hostnamen einrichten , den der Cassandra-Server als c ontactPoints ausführt. Port ist einfach der Überwachungsport für die Anforderung im Server. KeyspaceName ist der Namespace, der die Datenreplikation auf Knoten definiert, die auf einem Cassandra-bezogenen Konzept basiert.

4. Das Cassandra-Repository

Wir werden ein CassandraRepository für die Datenzugriffsschicht verwenden. Dies folgt der Spring Data Repository-Abstraktion, die sich darauf konzentriert, den Code zu abstrahieren, der zum Implementieren der Datenzugriffsschichten über verschiedene Persistenzmechanismen hinweg erforderlich ist.

4.1. Erstellen Sie das CassandraRepository

Erstellen wir das CassandraRepository , das in der Konfiguration verwendet werden soll:

@Repository public interface BookRepository extends CassandraRepository { // }

4.2. Konfiguration für CassandraRepository

Jetzt können wir die Konfiguration in Abschnitt 3.1 erweitern und @ AnnableCassandraRepositories- Annotation auf Klassenebene hinzufügen , um unser in Abschnitt 4.1 in CassandraConfig erstelltes Cassandra-Repository zu markieren :

@Configuration @EnableCassandraRepositories( basePackages = "com.baeldung.spring.data.cassandra.repository") public class CassandraConfig extends AbstractCassandraConfiguration { // }

5. Die Entität

Lassen Sie uns einen kurzen Blick auf die Entität werfen - die Modellklasse, die wir verwenden werden. Die Klasse ist mit Anmerkungen versehen und definiert zusätzliche Parameter für die Erstellung der Metadaten-Cassandra-Datentabelle im eingebetteten Modus.

Mit der Annotation @Table wird die Bean direkt einer Cassandra-Datentabelle zugeordnet. Außerdem wird jede Eigenschaft als Primärschlüsseltyp oder einfache Spalte definiert:

@Table public class Book { @PrimaryKeyColumn( name = "isbn", ordinal = 2, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING) private UUID id; @PrimaryKeyColumn( name = "title", ordinal = 0, type = PrimaryKeyType.PARTITIONED) private String title; @PrimaryKeyColumn( name = "publisher", ordinal = 1, type = PrimaryKeyType.PARTITIONED) private String publisher; @Column private Set tags = new HashSet(); // standard getters and setters }

6. Testen mit einem eingebetteten Server

6.1. Maven-Abhängigkeiten

Wenn Sie Cassandra im eingebetteten Modus ausführen möchten (ohne manuell einen separaten Cassandra-Server zu installieren), müssen Sie der pom.xml die Abhängigkeiten hinzufügen, die sich auf Cassandra -Einheiten beziehen :

 org.cassandraunit cassandra-unit-spring 2.1.9.2 test   org.cassandraunit cassandra-unit     org.cassandraunit cassandra-unit-shaded 2.1.9.2 test   org.hectorclient hector-core 2.0-0 

Es ist möglich, einen eingebetteten Cassandra-Server zum Testen dieser Anwendung zu verwenden . Der Hauptvorteil ist, dass Sie Cassandra nicht explizit installieren möchten.

Dieser eingebettete Server ist auch mit Spring JUnit Tests kompatibel. Hier können wir SpringJUnit4ClassRunner mithilfe der Annotation @RunWith zusammen mit dem eingebetteten Server festlegen . So ist es möglich, eine vollständige Testsuite zu implementieren, ohne dass ein externer Cassandra-Dienst ausgeführt wird.

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CassandraConfig.class) public class BookRepositoryIntegrationTest { // }

6.2. Starten und Stoppen des Servers

Sie können diesen Abschnitt ignorieren, wenn Sie einen externen Cassandra-Server ausführen.

Wir müssen den Server einmal für die gesamte Testsuite starten, daher ist die Serverstartmethode mit der Annotation @BeforeClass gekennzeichnet :

@BeforeClass public static void startCassandraEmbedded() { EmbeddedCassandraServerHelper.startEmbeddedCassandra(); Cluster cluster = Cluster.builder() .addContactPoints("127.0.0.1").withPort(9142).build(); Session session = cluster.connect(); }

Als nächstes müssen wir sicherstellen, dass der Server nach Abschluss der Ausführung der Testsuite gestoppt wird:

@AfterClass public static void stopCassandraEmbedded() { EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); }

6.3. Datentabelle bereinigen

Es wird empfohlen, die Datentabelle vor jeder Testausführung zu löschen und zu erstellen, um unerwartete Ergebnisse aufgrund der manipulierten Daten in früheren Testausführungen zu vermeiden.

Jetzt können wir die Datentabelle erstellen, wenn der Server gestartet wird:

@Before public void createTable() { adminTemplate.createTable( true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap()); }

und fallen nach jeder einzelnen Testfallausführung:

@After public void dropTable() { adminTemplate.dropTable(CqlIdentifier.cqlId(DATA_TABLE_NAME)); }

7. Datenzugriff mit CassandraRepository

Wir können das oben erstellte BookRepository direkt verwenden , um die Daten in der Cassandra-Datenbank beizubehalten, zu bearbeiten und abzurufen.

7.1. Speichern Sie ein neues Buch

Wir können ein neues Buch in unserem Buchladen speichern:

Book javaBook = new Book( UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software")); bookRepository.save(ImmutableSet.of(javaBook));

Dann können wir die Verfügbarkeit des eingefügten Buches in der Datenbank überprüfen:

Iterable books = bookRepository.findByTitleAndPublisher( "Head First Java", "O'Reilly Media"); assertEquals(javaBook.getId(), books.iterator().next().getId());

7.2. Aktualisieren Sie ein vorhandenes Buch

Lat beginnt mit dem Einfügen eines neuen Buches:

Book javaBook = new Book( UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software")); bookRepository.save(ImmutableSet.of(javaBook));

Holen wir uns das Buch mit dem Titel:

Iterable books = bookRepository.findByTitleAndPublisher( "Head First Java", "O'Reilly Media");

Dann ändern wir den Titel des Buches:

javaBook.setTitle("Head First Java Second Edition"); bookRepository.save(ImmutableSet.of(javaBook));

Überprüfen Sie abschließend, ob der Titel in der Datenbank aktualisiert wurde:

Iterable books = bookRepository.findByTitleAndPublisher( "Head First Java Second Edition", "O'Reilly Media"); assertEquals( javaBook.getTitle(), updateBooks.iterator().next().getTitle());

7.3. Löschen Sie das vorhandene Buch

Ein neues Buch einfügen:

Book javaBook = new Book( UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software")); bookRepository.save(ImmutableSet.of(javaBook));

Löschen Sie dann das neu eingegebene Buch:

bookRepository.delete(javaBook); 

Jetzt können wir nach dem Löschen suchen:

Iterable books = bookRepository.findByTitleAndPublisher( "Head First Java", "O'Reilly Media"); assertNotEquals(javaBook.getId(), books.iterator().next().getId());

Dies führt dazu, dass eine NoSuchElementException aus dem Code ausgelöst wird, um sicherzustellen, dass das Buch gelöscht wird.

7.4. Alle Bücher finden

Legen Sie zuerst ein neues Buch ein:

Book javaBook = new Book( UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software")); Book dPatternBook = new Book( UUIDs.timeBased(), "Head Design Patterns","O'Reilly Media", ImmutableSet.of("Computer", "Software")); bookRepository.save(ImmutableSet.of(javaBook)); bookRepository.save(ImmutableSet.of(dPatternBook));

Alle Bücher finden:

Iterable books = bookRepository.findAll();

Dann können wir die Anzahl der verfügbaren Bücher in der Datenbank überprüfen:

int bookCount = 0; for (Book book : books) bookCount++; assertEquals(bookCount, 2);

8. Fazit

Wir haben eine grundlegende praktische Einführung in die Cassandra mit Spring-Daten unter Verwendung des gängigsten Ansatzes unter Verwendung des CassandraRepository -Datenzugriffsmechanismus durchlaufen.

Die Implementierung der obigen Codefragmente und Beispiele finden Sie in meinem GitHub-Projekt - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.