2014-07-10 12 views
9

Voglio creare un'API RESTful con Java e Cassandra 2.x (su framework Jersey). Sono nuovo di entrambe le tecnologie, quindi vorrei chiederti è il modo corretto di integrare e condividere il driver Cassandra.Qual è il modo giusto per utilizzare il driver Cassandra da un'applicazione Web

0. Prendi il conducente se Maven

<dependency> 
      <groupId>com.datastax.cassandra</groupId> 
      <artifactId>cassandra-driver-core</artifactId> 
      <version>2.0.3</version> 
</dependency> 

funzionalità 1. guidatore Avvolgere con una classe Cliente:

package com.example.cassandra; 

import com.datastax.driver.core.*; 

public class Client { 

    private Cluster cluster; 
    private Session session; 

    public Client(String node) { 
     connect(node); 
    } 

    private void connect(String node) { 
     cluster = Cluster.builder() 
      .addContactPoint(node) 
      .build(); 

     session = cluster.connect(); 
    } 

    public ResultSet execute(String cql3) { 
     return session.execute(cql3); 
    } 

    public void close() { 
     cluster.close(); 
    } 

} 

2. I insatiate il cliente in ContextListener e condividere tuttavia attributo contesto

package com.example.listener; 

import javax.servlet.ServletContext; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 

import com.example.cassandra.Client; 

public class ExampleContextListener implements ServletContextListener { 

    Client cassandraClient; 

    public void contextInitialized(ServletContextEvent servletContextEvent) { 
     ServletContext ctx = servletContextEvent.getServletContext(); 

     cassandraClient = new Client(ctx.getInitParameter("DBHost")); 
     ctx.setAttribute("DB", cassandraClient); 
    } 

    public void contextDestroyed(ServletContextEvent servletContextEvent) { 
     cassandraClient.close(); 
    } 

} 

3. Ora ho il client dal contesto di servlet e utilizzarlo

Client client = (Client) context.getAttribute("DB"); 
client.execute("USE testspace;"); 

ResultSet rs = client.execute("SELECT * from users;"); 
for (Row row : rs) { 
    output += row.getString("lname") + "|"; 
} 

E 'questo il modo corretto per farlo (sia da prestazioni e punto di vista architettonico)?

esempio completa accessibile: https://github.com/lukaszkujawa/jersey-cassandra

+0

Ciao, mi chiedevo se mi si potrebbe dire il modo migliore l'hai adottato nella vostra web app? – niaomingjian

risposta

9

ho appena sviluppato che cosa avete intenzione di sviluppare. Ciò che hai scritto funziona, ma non è il mio approccio preferito. Preferirei creare un Singleton (dal momento che 1 sessione è sufficiente per un'applicazione). A seguito di modello di Singleton di Joshua Bloch enum qui è quello che ho fatto

public enum Cassandra { 

     DB; 

     private Session session; 
     private Cluster cluster; 
     private static final Logger LOGGER = LoggerFactory.getLogger(Cassandra.class); 

     /** 
     * Connect to the cassandra database based on the connection configuration provided. 
     * Multiple call to this method will have no effects if a connection is already established 
     * @param conf the configuration for the connection 
     */ 
     public void connect(ConnectionCfg conf) { 
      if (cluster == null && session == null) { 
       cluster = Cluster.builder().withPort(conf.getPort()).withCredentials(conf.getUsername(), conf.getPassword()).addContactPoints(conf.getSeeds()).build(); 
       session = cluster.connect(conf.getKeyspace()); 
      } 
      Metadata metadata = cluster.getMetadata(); 
      LOGGER.info("Connected to cluster: " + metadata.getClusterName() + " with partitioner: " + metadata.getPartitioner()); 
      metadata.getAllHosts().stream().forEach((host) -> { 
       LOGGER.info("Cassandra datacenter: " + host.getDatacenter() + " | address: " + host.getAddress() + " | rack: " + host.getRack()); 
      }); 
     } 

     /** 
     * Invalidate and close the session and connection to the cassandra database 
     */ 
     public void shutdown() { 
      LOGGER.info("Shutting down the whole cassandra cluster"); 
      if (null != session) { 
       session.close(); 
      } 
      if (null != cluster) { 
       cluster.close(); 
      } 
     } 

     public Session getSession() { 
      if (session == null) { 
       throw new IllegalStateException("No connection initialized"); 
      } 
      return session; 
     } 
} 

E in chi ascolta contesto io chiamo la connessione o l'arresto. Dal momento che tutte le eccezioni nel nuovo driver sono deselezionate, il mio suggerimento per voi è quello di creare la propria implementazione del Jersey ExceptionMapper mappando DriverException. Un'altra cosa, pensa a lavorare con PreparedStatements piuttosto che con Strings in modo che Cassandra analizzi la query una sola volta. Nella mia applicazione ho seguito i modelli di cui sopra anche per le query (un enum singleton che prepara le istruzioni quando vengono caricate per la prima volta e poi espone i metodi per usare queste istruzioni).

HTH, Carlo

+0

Grazie ancora Carlo. Come puoi vedere ho rinunciato a PHP e sono passato a Java. Non ci saranno problemi con i driver qui;) –

+0

Sicuramente nessun problema. Il nuovo driver è molto ben fatto e ciò che offre Jersey fuori dalla scatola per il riposo è semplicemente fantastico. Non ti pentirai della tua scelta! Divertiti, Carlo –

+1

Ciao Carlo, intendi dire che solo un oggetto di sessione Cassandra singleton è sufficiente per un'applicazione web. se il mio numero di utenti dell'applicazione è 1000. l'oggetto singola sessione soddisferà il mio scenario? per favore chiarisci la mia richiesta. grazie – Gnana

Problemi correlati