1. ภาพรวม
Cloud Spanner เป็น RDBMS แบบหลายภูมิภาคที่มีความพร้อมใช้งานสูง รองรับการปรับขนาดในแนวนอน และหลายภูมิภาค ห้องทดลองโค้ดนี้จะใช้อินสแตนซ์ที่เล็กที่สุดของ Cloud Spanner แต่อย่าลืมที่จะปิดการทำงานเมื่อเสร็จสิ้น!
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้ Cloud Spanner เพื่อบันทึกและเรียกข้อมูลด้วย Spring Boot
สิ่งที่คุณต้องมี
คุณจะใช้บทแนะนำนี้อย่างไร
คุณจะให้คะแนนความพึงพอใจสำหรับประสบการณ์การใช้บริการ Google Cloud Platform อย่างไร
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก
- ลงชื่อเข้าใช้ Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ (หากยังไม่มีบัญชี Gmail หรือ G Suite คุณต้องสร้างบัญชี)
โปรดจดจำรหัสโปรเจ็กต์ ซึ่งเป็นชื่อที่ไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมด (ชื่อด้านบนมีคนใช้แล้ว และจะใช้ไม่ได้ ขออภัย) และจะมีการอ้างอิงใน Codelab ว่า PROJECT_ID
ในภายหลัง
- ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร Google Cloud
การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี ตรวจสอบว่าคุณได้ทำตามวิธีการใน "การล้างข้อมูล" ซึ่งจะแนะนำคุณเกี่ยวกับวิธีปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD
เปิดใช้งาน Cloud Shell
- คลิกเปิดใช้งาน Cloud Shell จาก Cloud Console
หากคุณไม่เคยเริ่มต้นใช้งาน Cloud Shell มาก่อน คุณจะเห็นหน้าจอตรงกลาง (ครึ่งหน้าล่าง) ซึ่งอธิบายว่านี่คืออะไร หากเป็นเช่นนั้น ให้คลิกดำเนินการต่อ (คุณจะไม่เห็นการดำเนินการนี้อีก) หน้าจอแบบครั้งเดียวมีลักษณะดังนี้
การจัดสรรและเชื่อมต่อกับ Cloud Shell ใช้เวลาเพียงไม่กี่นาที
เครื่องเสมือนนี้เต็มไปด้วยเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักขนาด 5 GB ที่ทำงานอย่างต่อเนื่องใน Google Cloud ซึ่งจะช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานส่วนใหญ่ใน Codelab นี้สามารถทำได้โดยใช้เบราว์เซอร์หรือ Chromebook เท่านั้น
เมื่อเชื่อมต่อกับ Cloud Shell คุณควรเห็นว่าได้รับการตรวจสอบสิทธิ์แล้ว และโปรเจ็กต์ได้รับการตั้งค่าเป็นรหัสโปรเจ็กต์แล้ว
- เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list
เอาต์พุตจากคำสั่ง
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
gcloud config list project
เอาต์พุตจากคำสั่ง
[core] project = <PROJECT_ID>
หากไม่ใช่ ให้ตั้งคำสั่งด้วยคำสั่งนี้
gcloud config set project <PROJECT_ID>
เอาต์พุตจากคำสั่ง
Updated property [core/project].
3. เริ่มต้น Cloud Spanner
เปิดใช้ Cloud Spanner API โดยใช้ gcloud CLI:
gcloud services enable spanner.googleapis.com
สร้างอินสแตนซ์ Cloud Spanner
gcloud spanner instances create spanner-instance \ --config=regional-us-central1 \ --nodes=1 --description="A Spanner Instance"
สร้างฐานข้อมูลภายในอินสแตนซ์
gcloud spanner databases create orders \ --instance=spanner-instance
สร้างไฟล์ schema.ddl
เพื่ออธิบายสคีมาข้อมูล
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
ใช้สคีมากับฐานข้อมูล Cloud Spanner
gcloud spanner databases ddl update orders \ --instance=spanner-instance \ --ddl="$(<schema.ddl)"
4. เปิดเครื่องแอปพลิเคชัน Java สำหรับ Spring Boot ใหม่
จากสภาพแวดล้อม Cloud Shell ให้ใช้คำสั่งต่อไปนี้เพื่อเริ่มต้นและเปิดเครื่องแอปพลิเคชัน 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
การดำเนินการนี้จะสร้างไดเรกทอรี spanner-example/
ใหม่พร้อมด้วยโปรเจ็กต์ Maven ใหม่ รวมถึง pom.xml
ของ Maven, Wrapper ของ Maven และจุดเข้าใช้งานของแอปพลิเคชัน
ในไฟล์ pom.xml
ให้เพิ่มเงื่อนไขเริ่มต้น 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>
ใน application.properties ให้กำหนดค่าข้อมูลการเชื่อมต่อฐานข้อมูล Spanner ดังนี้
spanner-example/src/main/resources/application.properties
spring.cloud.gcp.spanner.instance-id=spanner-instance spring.cloud.gcp.spanner.database=orders
ตรวจสอบว่าได้ตั้งค่า JAVA_HOME
เป็นเวอร์ชันที่ถูกต้องแล้ว
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/
สร้างแอปอีกครั้งเพื่อตรวจสอบว่าการกำหนดค่า Maven ถูกต้อง โดยทำดังนี้
./mvnw package
5. สร้างเอนทิตี
การรองรับ Spring Data Spanner ของ Spring Cloud GCP จะช่วยให้คุณสร้างออบเจ็กต์ Java และการแมป ORM แบบระบุตัวตนกับตาราง Spanner ได้อย่างง่ายดายโดยใช้ข้อมูล Spring
ก่อนอื่นให้สร้างคลาส "สินค้าในคำสั่งซื้อ"
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;
}
สำหรับความสัมพันธ์ระดับบนสุด/ย่อยใน Spanner คุณควรใช้คีย์หลักแบบผสม ในตัวอย่างนี้ คีย์ผสมคือ order_id
และ order_item_id
จากนั้นสร้างชั้นเรียน "คำสั่งซื้อ" ดังนี้
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;
}
คลาสนี้ใช้คำอธิบายประกอบ @Interleaved
เพื่อสร้างความสัมพันธ์แบบ 1 ต่อหลายรายการกับรายการในคำสั่งซื้อ
6. สร้างอินเทอร์เฟซ OrderRepository
สร้างชั้นเรียน OrderRepository
ที่มีเนื้อหาต่อไปนี้
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> {
}
อินเทอร์เฟซจะขยาย SpannerRepository<Order, String>
โดยที่ Order
คือคลาสโดเมนและ String
เป็นประเภทคีย์หลัก Spring Data จะให้สิทธิ์เข้าถึง CRUD ผ่านอินเทอร์เฟซนี้โดยอัตโนมัติและคุณไม่จำเป็นต้องสร้างโค้ดเพิ่มเติม
7. สร้างตัวควบคุม REST สำหรับการดำเนินการขั้นพื้นฐาน
เปิดคลาส DemoApplication
ของแอปพลิเคชันหลัก และแก้ไขให้มีลักษณะดังนี้
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. เรียกใช้แอปพลิเคชัน
สร้างแอปพลิเคชันใหม่และเรียกใช้
./mvnw spring-boot:run
สัญญาณควรเริ่มทำงานอย่างถูกต้องและรอสัญญาณที่พอร์ต 8080
คุณโพสต์ระเบียนคำสั่งซื้อไปยังปลายทางได้โดยทำดังนี้
curl -H"Content-Type: application/json" -d'{"description": "My orders", "items": [{"description": "Android Phone", "quantity": "1"}]}' \ http://localhost:8080/api/orders
คำสั่งซื้อควรตอบกลับด้วยUUID
ของคำสั่งซื้อ
จากนั้นคุณสามารถรับคำสั่งซื้อด้วย UUID
:
curl http://localhost:8080/api/orders/REPLACE_WITH_ORDER_UUID
หากต้องการดูวิธีการจัดเก็บข้อมูล Cloud Spanner ให้ไปที่ Cloud Console และไปที่เครื่องมือสำรวจ → อินสแตนซ์ Spanner → ฐานข้อมูลคำสั่งซื้อ → ตารางคำสั่งซื้อ → ข้อมูล
9. ล้างข้อมูล
หากต้องการล้างข้อมูล ให้ลบอินสแตนซ์ Spanner เพื่อไม่ให้มีการเรียกเก็บเงินอีก
gcloud spanner instances delete spanner-instance -q
10. ยินดีด้วย
ใน Codelab นี้ คุณได้สร้างแอปพลิเคชัน CLI แบบอินเทอร์แอกทีฟที่สามารถจัดเก็บและเรียกข้อมูลจาก Cloud Spanner
ดูข้อมูลเพิ่มเติม
- Cloud Spanner: https://cloud.google.com/spanner/
- โปรเจ็กต์ GCP ฤดูใบไม้ผลิ: https://googlecloudplatform.github.io/spring-cloud-gcp/reference/html/
- Spring ในที่เก็บ GitHub ของ GCP: https://github.com/spring-cloud/spring-cloud-gcp
- Java บน Google Cloud Platform: https://cloud.google.com/java/
ใบอนุญาต
ผลงานนี้ได้รับอนุญาตภายใต้ใบอนุญาตทั่วไปครีเอทีฟคอมมอนส์แบบระบุแหล่งที่มา 2.0