Google Cloud Datastore هي قاعدة بيانات مستنِدة إلى تنسيق NoSQL ومصمَّمة لتوفير إمكانية التوسّع التلقائي والأداء العالي وسهولة تطوير التطبيقات.
ما ستتعرّف عليه
- كيفية استخدام Cloud Datastore لحفظ واسترداد عناصر Java في Spring Boot
المتطلبات
كيف ستستخدم هذا البرنامج التعليمي؟
ما هو تقييمك لتجربة استخدام خدمات Google Cloud Platform؟
إعداد البيئة بالسرعة التي تناسبك
إذا لم يكن لديك حساب على Google (Gmail أو Google Apps)، عليك إنشاء حساب. سجِّل الدخول إلى "وحدة تحكّم Google Cloud Platform" (console.cloud.google.com) وأنشِئ مشروعًا جديدًا:
تذكَّر معرّف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (الاسم أعلاه مستخدَم حاليًا ولن يكون متاحًا لك، نأسف لذلك). سيتم الإشارة إليه لاحقًا في هذا الدرس العملي باسم PROJECT_ID
.
بعد ذلك، عليك تفعيل الفوترة في Cloud Console من أجل استخدام موارد Google Cloud.
لن تكلفك تجربة هذا الدرس البرمجي أكثر من بضعة دولارات، ولكن قد تكون التكلفة أعلى إذا قررت استخدام المزيد من الموارد أو إذا تركتها قيد التشغيل (راجِع قسم "التنظيف" في نهاية هذا المستند).
يمكن للمستخدمين الجدد في Google Cloud Platform الاستفادة من فترة تجريبية مجانية بقيمة 300 دولار أمريكي.
تفعيل Google Cloud Shell
من وحدة تحكّم Google Cloud Platform، انقر على رمز Cloud Shell في شريط الأدوات العلوي الأيسر:
ثم انقر على "بدء Cloud Shell":
ينبغي ألا تستغرق إدارة الحسابات والاتصال بالبيئة أكثر من بضع لحظات.
يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. وتوفِّر هذه الآلة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتمّ تشغيله على Google Cloud، ما يحسّن كثيرًا أداء الشبكة والمصادقة. ويمكن إتمام معظم عملك إن لم يكن كلّه في هذا الدرس ببساطة من خلال متصفّح أو جهاز Google Chromebook فقط.
بعد الاتصال بـ Cloud Shell، من المفترض أن ترى أنّه تم إثبات هويتك وأنّ المشروع تم ضبطه على PROJECT_ID.
نفِّذ الأمر التالي في Cloud Shell للتأكّد من إكمال عملية المصادقة:
gcloud auth list
ناتج الأمر
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
ناتج الأمر
[core] project = <PROJECT_ID>
إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:
gcloud config set project <PROJECT_ID>
ناتج الأمر
Updated property [core/project].
في وحدة تحكّم Google Cloud Platform، انتقِل إلى القائمة -> Datastore (في قسم "مساحة التخزين").
إذا لم يسبق لك استخدام Datastore في المشروع الحالي، ستظهر لك شاشة "اختيار وضع Cloud Firestore". اختَر الخيار "وضع Datastore".
بعد ذلك، ستظهر لك شاشة "اختيار مكان تخزين البيانات". اختَر us-east1 أو أي موقع جغرافي إقليمي آخر وانقر على "إنشاء قاعدة بيانات":
من بيئة CloudShell، استخدِم الأمر التالي لتهيئة تطبيق Spring Boot جديد وإعداده:
$ curl https://start.spring.io/starter.tgz \ -d packaging=war \ -d dependencies=cloud-gcp \ -d baseDir=datastore-example \ -d bootVersion=2.1.1.RELEASE | tar -xzvf -
سيؤدي ذلك إلى إنشاء دليل datastore-example/
جديد يتضمّن مشروع Maven جديدًا، بالإضافة إلى pom.xml
من Maven، وهو برنامج تضمين Maven، فضلاً عن نقطة دخول التطبيق.
سيوفر تطبيقنا واجهة سطر أوامر للمستخدمين لإدخال الأوامر والاطّلاع على النتائج. سننشئ فئة لتمثيل كتاب ثم نحفظها في Cloud Datastore باستخدام Datastore Repository.
علينا أيضًا إضافة تبعية ضرورية أخرى إلى pom.xml
.
افتح "أداة تعديل الرموز البرمجية على الويب" من خلال النقر على تشغيل أداة تعديل الرموز البرمجية من قائمة Cloud Shell.
بعد تحميل المحرّر، عدِّل الملف pom.xml
لإضافة تبعية Spring Data Cloud Datastore Spring Boot starter:
pom.xml
<project>
...
<dependencies>
...
<!-- Add GCP Datastore Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-data-datastore</artifactId>
</dependency>
<!-- Add Spring Shell Starter -->
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell-starter</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
</project>
باستخدام المحرّر، أنشئ الفئة Book
مع المحتوى التالي:
datastore-example/src/main/java/com/example/demo/Book.java
package com.example.demo;
import org.springframework.cloud.gcp.data.datastore.core.mapping.Entity;
import org.springframework.data.annotation.Id;
@Entity(name = "books")
public class Book {
@Id
Long id;
String title;
String author;
int year;
public Book(String title, String author, int year) {
this.title = title;
this.author = author;
this.year = year;
}
public long getId() {
return this.id;
}
@Override
public String toString() {
return "Book{" +
"id=" + this.id +
", title='" + this.title + '\'' +
", author='" + this.author + '\'' +
", year=" + this.year +
'}';
}
}
كما ترى، هذا POJO بسيط. يتم وضع تعليق توضيحي على الفئة باستخدام @Entity
للإشارة إلى أنّه يمكن تخزينها في Datastore وتوفير اسم النوع (يمكنك اعتبار النوع جدولاً في قواعد بيانات SQL، راجِع المستندات لمزيد من التفاصيل). اسم النوع اختياري، وفي حال حذفه، سيتم إنشاء اسم النوع استنادًا إلى اسم الفئة.
يُرجى العِلم أنّنا أضفنا تعليقًا توضيحيًا إلى السمة id
باستخدام @Id
. يشير ذلك إلى أنّنا نريد استخدام هذا الحقل كجزء المعرّف من مفتاح Datastore. يحتاج كل عنصر Datastore إلى معرّف. الأنواع المقبولة هي String
وLong
.
نحن نتجاوز طريقة toString
لجعل التمثيل السلسلي للكائنات أكثر قابلية للقراءة، وسيكون ذلك مفيدًا عند طباعتها.
لا تنسَ حفظ الملف.
أنشئ فئة BookRepository
تتضمّن المحتوى التالي:
datastore-example/src/main/java/com/example/demo/BookRepository.java
package com.example.demo;
import java.util.List;
import org.springframework.cloud.gcp.data.datastore.repository.DatastoreRepository;
public interface BookRepository extends DatastoreRepository<Book, Long> {
List<Book> findByAuthor(String author);
List<Book> findByYearGreaterThan(int year);
List<Book> findByAuthorAndYear(String author, int year);
}
توسّع الواجهة DatastoreRepository<Book, Long>
حيث Book
هي فئة النطاق وLong
هي نوع Id
. نحدّد ثلاث طرق طلب بحث في مستودعنا يتم إنشاء عمليات التنفيذ لها تلقائيًا في الخلفية.
الرقم الأول هو findByAuthor
. كما يمكنك تخمين ذلك، سيؤدي تنفيذ هذه الطريقة إلى تنفيذ طلب بحث سيستخدم قيمة يقدّمها المستخدم في فلتر الشرط للمساواة مع حقل المؤلف.
ينفّذ findByYearGreaterThan
طريقة طلب بحث يفلتر حقل السنة ليكون أكبر من القيمة التي يقدّمها المستخدم.
ينفّذ findByAuthorAndYear
طلب بحث عن الكيانات التي تتطابق فيها حقول المؤلف والسنة مع القيم التي يقدّمها المستخدم.
افتح فئة التطبيق الرئيسية DemoApplication
وعدِّلها لتصبح على النحو التالي:
datastore-example/src/main/java/com/example/demo/DemoApplication.java
package com.example.demo;
import java.util.List;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
@SpringBootApplication
public class DemoApplication {
@Autowired
BookRepository bookRepository;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@ShellMethod("Saves a book to Cloud Datastore: save-book <title> <author> <year>")
public String saveBook(String title, String author, int year) {
Book savedBook = this.bookRepository.save(new Book(title, author, year));
return savedBook.toString();
}
@ShellMethod("Loads all books")
public String findAllBooks() {
Iterable<Book> books = this.bookRepository.findAll();
return Lists.newArrayList(books).toString();
}
@ShellMethod("Loads books by author: find-by-author <author>")
public String findByAuthor(String author) {
List<Book> books = this.bookRepository.findByAuthor(author);
return books.toString();
}
@ShellMethod("Loads books published after a given year: find-by-year-after <year>")
public String findByYearAfter(int year) {
List<Book> books = this.bookRepository.findByYearGreaterThan(year);
return books.toString();
}
@ShellMethod("Loads books by author and year: find-by-author-year <author> <year>")
public String findByAuthorYear(String author, int year) {
List<Book> books = this.bookRepository.findByAuthorAndYear(author, year);
return books.toString();
}
@ShellMethod("Removes all books")
public void removeAllBooks() {
this.bookRepository.deleteAll();
}
}
لاحظ كيف أضفنا التعليق التوضيحي @ShellComponent
إلى الفئة. يُعلم ذلك Spring بأنّنا نريد استخدام هذه الفئة كمصدر لأوامر واجهة سطر الأوامر. سيتم عرض الطرق التي تمّت إضافة التعليقات التوضيحية إليها باستخدام @ShellMethod
كأوامر لواجهة سطر الأوامر في تطبيقنا.
نستخدم هنا الطرق التي حدّدناها في واجهة BookRepository: findByAuthor
وfindByYearGreaterThan
وfindByAuthorAndYear
. نستخدم أيضًا ثلاث طرق مدمجة: save
وfindAll
وdeleteAll
.
لنلقِ نظرة على طريقة saveBook
. ننشئ كائن Book
باستخدام القيم التي يقدّمها المستخدم للعنوان والمؤلف والسنة. كما ترى، لا نقدّم قيمة id
، لذا سيتم تخصيصها وتعيينها تلقائيًا لحقل المعرّف عند الحفظ. تقبل الطريقة save
كائنًا من النوع Book
وتحفظه في Cloud Datastore. تعرض هذه الطريقة عنصر Book
مع تعبئة جميع الحقول، بما في ذلك الحقل id
. في النهاية، نعرض تمثيلاً على شكل سلسلة نصية لهذا العنصر.
تعمل بقية الطرق بشكل مشابه: فهي تقبل المَعلمات التي تم تمريرها إلى طرق المستودع المناسبة وتعرض النتائج على شكل سلسلة.
لإنشاء التطبيق وبدء تشغيله، نفِّذ الأمر التالي في Cloud Shell (من جذر المشروع datastore-example/
حيث يقع pom.xml
) :
$ mvn spring-boot:run
بعد اكتمال مرحلة الإنشاء بنجاح، سيظهر شعار Spring وسيظهر طلب الصدفة:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.1.RELEASE) shell:>
يمكنك الآن تجربة الأوامر التي حدّدناها سابقًا. للاطّلاع على قائمة الأوامر، استخدِم أمر المساعدة:
shell:> help ... find-all-books: Loads all books find-by-author: Loads books by author: find-by-author <author> find-by-author-year: Loads books by author and year: find-by-author-year <author> <year> find-by-year-after: Loads books published after a given year: find-by-year-after <year> remove-all-books: Removes all books save-book: Saves a book to Cloud Datastore: save-book <title> <author> <year>
جرّب ما يلي:
- أنشئ بعض الكتب باستخدام الأمر
save-book
- إجراء بحث باستخدام الأمر
find-all-books
- البحث عن كتب لمؤلف معيّن (
find-by-author <author>
) - البحث عن كتب تم نشرها بعد سنة معيّنة (
find-by-year-after <year>
) - البحث عن كتب لمؤلف معيّن وفي سنة معيّنة (
find-by-author-year <author> <year>
)
للاطّلاع على كيفية تخزين الكيانات في Cloud Datastore، انتقِل إلى GCP Console وانتقِل إلى القائمة -> Datastore (في قسم "مساحة التخزين") -> الكيانات (اختَر مساحة الاسم "[default]" ونوع "الكتب"، إذا لزم الأمر).
لإجراء عملية تنظيف، أزِل جميع الكتب باستخدام الأمر remove-all-books
الذي يحمل الاسم المناسب من واجهة التطبيق.
shell:> remove-all-books
للخروج من التطبيق، استخدِم أمر الإنهاء، ثم Ctrl+C.
في هذا الدرس التطبيقي حول الترميز، أنشأت تطبيقًا تفاعليًا لواجهة سطر الأوامر يمكنه تخزين العناصر واسترجاعها من Cloud Datastore.
مزيد من المعلومات
- Cloud Datastore: https://cloud.google.com/datastore/
- Spring Shell: https://projects.spring.io/spring-shell/
- مشروع Spring on GCP: http://cloud.spring.io/spring-cloud-gcp/
- مستودع Spring on GCP GitHub: https://github.com/spring-cloud/spring-cloud-gcp
- Java على Google Cloud Platform: https://cloud.google.com/java/
الترخيص
يخضع هذا العمل لترخيص Creative Commons Attribution 2.0 Generic License.