1. نظرة عامة
إنّ Cloud Spanner هو نظام RDBMS متوفّر بشكل كبير وقابل للتطور أفقيًا ومتعدد المناطق. سيستخدم مختبر الترميز هذا أصغر مثيل من Cloud Spanner، ولكن لا تنسَ إيقاف الخدمة عند الانتهاء.
المعلومات التي ستطّلع عليها
- كيفية استخدام Cloud Spanner لحفظ البيانات واستردادها باستخدام Spring Boot
المتطلبات
كيف ستستخدم هذا البرنامج التعليمي؟
ما هو تقييمك لتجربتك في استخدام خدمات Google Cloud Platform؟
2. الإعداد والمتطلبات
إعداد بيئة ذاتية
- سجِّل الدخول إلى Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. (إذا لم يكن لديك حساب على Gmail أو G Suite، عليك إنشاء حساب.)
يُرجى تذكُّر رقم تعريف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (سبق أن تم استخدام الاسم أعلاه ولن يكون مناسبًا لك). ستتم الإشارة إليها لاحقًا في هذا الدرس التطبيقي حول الترميز باسم PROJECT_ID
.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد Google Cloud.
إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. احرص على اتّباع أي تعليمات في قسم "الحذف سريعًا". الذي يقدم لك نصائح حول كيفية إيقاف تشغيل الموارد حتى لا تتكبّد أي فواتير خارج نطاق هذا البرنامج التعليمي. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج الفترة التجريبية المجانية التي تبلغ قيمتها 300 دولار أمريكي.
تفعيل Cloud Shell
- من Cloud Console، انقر على تفعيل Cloud Shell .
إذا لم يسبق لك بدء تشغيل Cloud Shell، ستظهر لك شاشة وسيطة (الجزء السفلي غير المرئي من الصفحة) تصف ماهيتها. وفي هذه الحالة، انقر على متابعة (ولن تظهر لك مرة أخرى). إليك ما تبدو عليه هذه الشاشة التي تُستخدم لمرة واحدة:
من المفترَض أن تستغرق عملية توفير المتطلبات اللازمة والاتصال بخدمة Cloud Shell بضع دقائق فقط.
يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح أو جهاز 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 باستخدام 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 جديد، بالإضافة إلى برنامج Maven (pom.xml
)، وهو برنامج تضمين 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.property، اضبط معلومات اتصال قاعدة بيانات 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.
أولاً، قم بإنشاء فئة 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;
}
بالنسبة إلى علاقات الأصل/التابع في 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
لإنشاء علاقة واحد إلى العديد من العناصر.
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 ← مثيل Spanner ← قاعدة بيانات الطلبات ← جدول الطلبات ← البيانات.
9. تَنظيم
لإزالة هذا المحتوى، احذف مثيل Spanner كي لا يتحمّل أي رسوم بعد الآن.
gcloud spanner instances delete spanner-instance -q
10. تهانينا!
وفي هذا الدرس التطبيقي حول الترميز، أنشأت تطبيق CLI تفاعليًا يمكنه تخزين البيانات واستردادها من Cloud Spanner.
مزيد من المعلومات
- Cloud Spanner: https://cloud.google.com/spanner/
- بدء مشروع Google Cloud Platform: https://googlecloudplatform.github.io/spring-cloud-gcp/reference/html/
- الانتقال إلى مستودع GitHub في Google Cloud Platform: https://github.com/spring-cloud/spring-cloud-gcp
- Java على Google Cloud Platform: https://cloud.google.com/java/
الترخيص
هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.