1. Panoramica
Cloud Spanner è un RDBMS multiregionale a scalabilità orizzontale e ad alta disponibilità. Questo codelab utilizzerà l'istanza più piccola di Cloud Spanner, ma non dimenticare di arrestarla al termine.
Cosa imparerai a fare
- Come utilizzare Cloud Spanner per salvare e recuperare dati con Spring Boot
Che cosa ti serve
Come utilizzerai questo tutorial?
Come valuti la tua esperienza di utilizzo dei servizi Google Cloud Platform?
2. Configurazione e requisiti
Configurazione dell'ambiente autonomo
- Accedi alla console Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai già un account Gmail o G Suite, devi crearne uno.
Ricorda l'ID progetto, un nome univoco tra tutti i progetti Google Cloud (il nome sopra è già stato utilizzato e non funzionerà per te, mi dispiace). In questo codelab verrà chiamato PROJECT_ID.
- Successivamente, dovrai abilitare la fatturazione in Cloud Console per utilizzare le risorse Google Cloud.
L'esecuzione di questo codelab non dovrebbe costare molto, se non nulla. Assicurati di seguire le istruzioni riportate nella sezione "Pulizia", che ti consiglia come arrestare le risorse in modo da non incorrere in addebiti oltre questo tutorial. I nuovi utenti di Google Cloud possono beneficiare del programma prova senza costi di 300$.
Attiva Cloud Shell
- Nella console Cloud, fai clic su Attiva Cloud Shell
.
Se non hai mai avviato Cloud Shell, viene visualizzata una schermata intermedia (sotto la piega) che ne descrive le funzionalità. In questo caso, fai clic su Continua e non comparirà più. Ecco come si presenta la schermata intermedia:
Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.
Questa macchina virtuale è caricata con tutti gli strumenti per sviluppatori di cui avrai bisogno. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto semplicemente con un browser o con Chromebook.
Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è già autenticato e il progetto è già impostato sul tuo ID progetto.
- Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list
Output comando
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
gcloud config list project
Output comando
[core] project = <PROJECT_ID>
In caso contrario, puoi impostarlo con questo comando:
gcloud config set project <PROJECT_ID>
Output comando
Updated property [core/project].
3. Inizializza Cloud Spanner
Abilita l'API Cloud Spanner utilizzando gcloud CLI:
gcloud services enable spanner.googleapis.com
Crea un'istanza Cloud Spanner:
gcloud spanner instances create spanner-instance \ --config=regional-us-central1 \ --nodes=1 --description="A Spanner Instance"
Crea un database all'interno dell'istanza:
gcloud spanner databases create orders \ --instance=spanner-instance
Crea un file schema.ddl per descrivere lo schema dei dati:
cat << EOF > schema.ddl CREATE TABLE orders ( order_id STRING(36) NOT NULL, description STRING(255), creation_timestamp TIMESTAMP, ) PRIMARY KEY (order_id); CREATE TABLE order_items ( order_id STRING(36) NOT NULL, order_item_id STRING(36) NOT NULL, description STRING(255), quantity INT64, ) PRIMARY KEY (order_id, order_item_id), INTERLEAVE IN PARENT orders ON DELETE CASCADE; EOF
Applica lo schema al database Cloud Spanner:
gcloud spanner databases ddl update orders \ --instance=spanner-instance \ --ddl="$(<schema.ddl)"
4. Bootstrap di una nuova applicazione Java Spring Boot
Dall'ambiente Cloud Shell, utilizza questo comando per inizializzare e avviare una nuova applicazione Spring Boot:
$ curl https://start.spring.io/starter.tgz \ -d packaging=jar \ -d dependencies=cloud-gcp,web,lombok \ -d baseDir=spanner-example \ -d type=maven-project \ -d bootVersion=3.2.6 | tar -xzvf - $ cd spanner-example
Verrà creata una nuova directory spanner-example/ con un nuovo progetto Maven, oltre a pom.xml, un wrapper Maven, e un punto di ingresso dell'applicazione.
Nel file pom.xml, aggiungi lo starter Spring Data Cloud Spanner.
spanner-example/pom.xml
<project>
...
<dependencies>
...
<!-- Add Spring Cloud GCP Spanner Starter -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
</dependency>
...
</dependencies>
...
</project>
In application.properties, configura le informazioni di connessione al database Spanner:
spanner-example/src/main/resources/application.properties
spring.cloud.gcp.spanner.instance-id=spanner-instance spring.cloud.gcp.spanner.database=orders
Assicurati che JAVA_HOME sia impostato sulla versione corretta:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/
Ricompila l'app per assicurarti che la configurazione di Maven sia corretta:
./mvnw package
5. Crea le entità
Grazie al supporto di Spring Data Spanner di Spring Cloud GCP, puoi creare facilmente un oggetto Java e una mappatura ORM idiomatica a una tabella Spanner utilizzando Spring Data.
Per prima cosa, crea una classe Order Item.
spanner-example/src/main/java/com/example/demo/OrderItem.java
package com.example.demo;
import com.google.cloud.spring.data.spanner.core.mapping.Column;
import com.google.cloud.spring.data.spanner.core.mapping.PrimaryKey;
import com.google.cloud.spring.data.spanner.core.mapping.Table;
@Table(name="order_items")
@Data
class OrderItem {
@PrimaryKey(keyOrder = 1)
@Column(name="order_id")
private String orderId;
@PrimaryKey(keyOrder = 2)
@Column(name="order_item_id")
private String orderItemId;
private String description;
private Long quantity;
}
Per le relazioni padre/figlio in Spanner, devi utilizzare una chiave primaria composita. In questo esempio, la chiave composita è order_id e order_item_id.
Dopodiché, crea una classe Order:
spanner-example/src/main/java/com/example/demo/Order.java
package com.example.demo;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Data;
import com.google.cloud.spring.data.spanner.core.mapping.Column;
import com.google.cloud.spring.data.spanner.core.mapping.Interleaved;
import com.google.cloud.spring.data.spanner.core.mapping.PrimaryKey;
import com.google.cloud.spring.data.spanner.core.mapping.Table;
@Table(name="orders")
@Data
public class Order {
@PrimaryKey
@Column(name="order_id")
private String id;
private String description;
@Column(name="creation_timestamp")
private LocalDateTime timestamp;
@Interleaved
private List<OrderItem> items;
}
Questa classe utilizza l'annotazione @Interleaved per creare una relazione uno-a-molti con gli elementi dell'ordine.
6. Crea l'interfaccia OrderRepository
Crea la classe OrderRepository con i seguenti contenuti:
spanner-example/src/main/java/com/example/demo/OrderRepository.java
package com.example.demo;
import com.google.cloud.spring.data.spanner.repository.SpannerRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderRepository extends SpannerRepository<Order, String> {
}
L'interfaccia estende SpannerRepository<Order, String>, dove Order è la classe di dominio e String è il tipo di chiave primaria. Spring Data fornirà automaticamente l'accesso CRUD tramite questa interfaccia e non dovrai creare codice aggiuntivo.
7. Crea un controller REST per le operazioni di base
Apri la classe dell'applicazione principale DemoApplication e modificala in modo che abbia il seguente aspetto:
spanner-example/src/main/java/com/example/demo/DemoApplication.java
package com.example.demo;
import java.time.LocalDateTime;
import java.util.UUID;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
class OrderController {
private final OrderRepository orderRepository;
OrderController(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@GetMapping("/api/orders/{id}")
public Order getOrder(@PathVariable String id) {
return orderRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found"));
}
@PostMapping("/api/orders")
public String createOrder(@RequestBody Order order) {
// Spanner currently does not auto generate IDs
// Generate UUID on new orders
order.setId(UUID.randomUUID().toString());
order.setTimestamp(LocalDateTime.now());
order.getItems().forEach(item -> {
// Assign parent ID, and also generate child ID
item.setOrderId(order.getId());
item.setOrderItemId(UUID.randomUUID().toString());
});
Order saved = orderRepository.save(order);
return saved.getId();
}
}
8. Esegui l'applicazione
Ricrea ed esegui l'applicazione.
./mvnw spring-boot:run
Dovrebbe avviarsi correttamente e rimanere in ascolto sulla porta 8080.
Puoi pubblicare un record Ordine nell'endpoint:
curl -H"Content-Type: application/json" -d'{"description": "My orders", "items": [{"description": "Android Phone", "quantity": "1"}]}' \
http://localhost:8080/api/orders
Dovrebbe rispondere con l'UUID dell'ordine.
Puoi quindi recuperare l'ordine con UUID:
curl http://localhost:8080/api/orders/REPLACE_WITH_ORDER_UUID
Per vedere come vengono archiviati i dati in Cloud Spanner, vai alla console Cloud e vai a Spanner → Istanza Spanner → database ordini → tabella ordini → Dati.

9. Esegui la pulizia
Per eseguire la pulizia, elimina l'istanza Spanner in modo che non generi più addebiti.
gcloud spanner instances delete spanner-instance -q
10. Complimenti!
In questo codelab hai creato un'applicazione CLI interattiva in grado di archiviare e recuperare dati da Cloud Spanner.
Scopri di più
- Cloud Spanner: https://cloud.google.com/spanner/
- Progetto Spring su GCP: https://googlecloudplatform.github.io/spring-cloud-gcp/reference/html/
- Repository GitHub di Spring su GCP: https://github.com/spring-cloud/spring-cloud-gcp
- Java su Google Cloud: https://cloud.google.com/java/
Licenza
Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.