Cloud Datastore가 포함된 Spring Boot 애플리케이션

1. 개요

Google Cloud Datastore는 자동 확장, 고성능, 간편한 애플리케이션 개발을 위해 설계된 NoSQL 문서 데이터베이스입니다.

학습할 내용

  • Cloud Datastore를 사용하여 Spring Boot에서 Java 객체를 저장하고 검색하는 방법

필요한 항목

  • Google Cloud Platform 프로젝트
  • 브라우저(Chrome 또는 Firefox 등)

본 가이드를 어떻게 사용하실 계획인가요?

읽기만 할 계획입니다 읽은 다음 연습 활동을 완료할 계획입니다

귀하의 Google Cloud Platform 서비스 사용 경험을 평가해 주세요.

<ph type="x-smartling-placeholder"></ph> 초보자 중급 숙련도

2. 설정 및 요구사항

자습형 환경 설정

  1. Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
  • 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔은 고유한 문자열을 자동으로 생성합니다. 일반적으로는 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로 PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 다른 임의 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다.
  • 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
  1. 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스 또는 프로젝트를 삭제하면 됩니다. Google Cloud 신규 사용자는 300달러(USD) 상당의 무료 체험판 프로그램에 참여할 수 있습니다.

Cloud Shell 활성화

  1. Cloud Console에서 Cloud Shell 활성화853e55310c205094.png를 클릭합니다.

55efc1aaa7a4d3ad.png

Cloud Shell을 처음 시작하는 경우에는 무엇이 있는지 설명하는 중간 화면이 표시됩니다. 중간 화면이 표시되면 계속을 클릭합니다.

92662c6a846a5c.png

Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.

9f0e51b578fecce5.png

가상 머신에는 필요한 개발 도구가 모두 들어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저를 사용하여 수행할 수 있습니다.

Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 자신의 프로젝트 ID로 설정된 것을 확인할 수 있습니다.

  1. 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`
  1. Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project

명령어 결과

[core]
project = <PROJECT_ID>

또는 다음 명령어로 설정할 수 있습니다.

gcloud config set project <PROJECT_ID>

명령어 결과

Updated property [core/project].

3. Cloud Datastore 초기화

GCP 콘솔에서 메뉴 -> Datastore (스토리지 섹션) 또는 여기를 클릭하세요.

현재 프로젝트에서 Datastore를 사용한 적이 없는 경우 'Cloud Firestore 모드 선택' 화면이 표시됩니다. 'Datastore 모드' 옵션을 선택합니다.

f938295c7ff297f4.png

그런 다음 '데이터 저장 위치 선택' 화면이 표시됩니다. us-east1 또는 다른 리전 위치를 선택하고 '데이터베이스 만들기'를 클릭합니다.

916ac84fec10fae7.png

4. 새 Spring Boot Java 애플리케이션 부트스트랩

CloudShell 환경에서 다음 명령어를 사용하여 새 Spring Boot 애플리케이션을 초기화하고 부트스트랩합니다.

$ curl https://start.spring.io/starter.tgz \
  -d packaging=war \
  -d dependencies=cloud-gcp \
  -d type=maven-project \
  -d baseDir=datastore-example \
  -d bootVersion=3.0.5 | tar -xzvf -

이렇게 하면 새 Maven 프로젝트와 Maven의 pom.xml, Maven 래퍼, 애플리케이션 진입점과 함께 새 datastore-example/ 디렉터리가 생성됩니다.

애플리케이션은 사용자가 명령어를 입력하고 결과를 확인할 수 있는 CLI를 제공합니다. 도서를 나타내는 클래스를 만든 다음 Datastore 저장소를 사용하여 Cloud Datastore에 저장합니다.

필요한 종속 항목도 pom.xml에 하나 더 추가해야 합니다.

Cloud Shell 메뉴에서 편집기 열기를 클릭하여 웹 코드 편집기를 엽니다.

6d823258c76a7452.png

편집기가 로드되면 pom.xml 파일을 수정하여 Google Cloud Datastore Starter 및 Spring Shell Starter 종속 항목을 추가합니다.

pom.xml

<project>
  ...
  <dependencies>
        ...
        <!-- Add GCP Datastore Starter -->
        <dependency>
                <groupId>com.google.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>3.0.2</version>
        </dependency>

  </dependencies>
</project>

5. Book 클래스 만들기

편집기를 사용하여 다음 콘텐츠가 포함된 Book 클래스를 만듭니다.

datastore-example/src/main/java/com/example/demo/Book.java

package com.example.demo;

import com.google.cloud.spring.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입니다. 이 클래스는 Datastore에 저장될 수 있고 종류 이름을 제공할 수 있음을 나타내기 위해 @Entity로 주석이 달립니다. 종류를 SQL 데이터베이스의 테이블로 생각해 보세요. 자세한 내용은 문서를 참고하세요. 종류 이름은 선택사항입니다. 종류 이름을 생략하면 클래스 이름을 기준으로 종류 이름이 생성됩니다.

id 속성에 @Id 주석을 추가했습니다. 이는 이 필드를 Datastore 키의 식별자 부분으로 사용하려고 한다는 것을 나타냅니다. 모든 Datastore 항목에는 식별자가 필요합니다. 지원되는 유형은 StringLong입니다.

객체의 문자열 표현을 더 쉽게 읽을 수 있도록 toString 메서드를 재정의합니다. 이를 출력할 때 유용합니다.

6. BookRepository 인터페이스 만들기

다음 콘텐츠로 BookRepository 클래스를 만듭니다.

datastore-example/src/main/java/com/example/demo/BookRepository.java

package com.example.demo;

import java.util.List;

import com.google.cloud.spring.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는 도메인 클래스이고 LongId 유형입니다. 백그라운드에서 구현이 자동으로 생성되는 세 가지 쿼리 메서드를 저장소에 선언합니다.

첫 번째는 findByAuthor입니다. 추측할 수 있듯이 이 메서드의 구현은 작성자가 같음 필드에 대한 조건 필터에서 사용자가 제공한 값을 사용하는 쿼리를 실행합니다.

findByYearGreaterThan 메서드는 사용자가 제공한 값보다 큰 연도 필드를 필터링하는 쿼리를 실행합니다.

findByAuthorAndYear는 작성자 및 연도 필드가 사용자 제공 값과 일치하는 항목을 찾는 쿼리를 실행합니다.

7. 대화형 CLI 애플리케이션 만들기

기본 애플리케이션 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 주석을 다는 방식에 주목하세요. 그러면 이 클래스를 CLI 명령어의 소스로 사용하겠다고 Spring에 알립니다. @ShellMethod 주석이 달린 메서드는 애플리케이션에서 CLI 명령어로 노출됩니다.

여기서는 BookRepository 인터페이스에서 선언한 메서드 findByAuthor, findByYearGreaterThan, findByAuthorAndYear를 사용합니다. 또한 save, findAll, deleteAll라는 세 가지 내장 메서드를 사용합니다.

saveBook 메서드를 살펴보겠습니다. 사용자가 제공한 제목, 저자, 연도 값을 사용하여 Book 객체를 만듭니다. 보시다시피 id 값은 제공되지 않으므로 저장 시 자동으로 할당되어 id 필드에 할당됩니다. save 메서드는 Book 유형의 객체를 받아 Cloud Datastore에 저장합니다. 이 메서드는 id 필드를 포함하여 모든 필드가 채워진 Book 객체를 반환합니다. 마지막에는 이 객체의 문자열 표현을 반환합니다.

나머지 메서드는 비슷하게 작동합니다. 즉, 적절한 저장소 메서드에 전달된 매개변수를 허용하고 문자열화된 결과를 반환합니다.

8. 애플리케이션 실행

애플리케이션을 빌드하고 시작하려면 먼저 JAVA_HOME이 올바른 버전으로 설정되어 있는지 확인합니다.

$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Cloud Shell에서 pom.xml가 있는 datastore-example/ 프로젝트의 루트에서 다음 명령어를 실행합니다.

$ ./mvnw spring-boot:run
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

빌드 단계가 완료되면 스프링 로고가 표시되고 셸 프롬프트가 표시됩니다.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.5)



shell:>

이제 앞에서 정의한 명령어로 실험해 볼 수 있습니다. 명령어 목록을 보려면 help 명령어를 사용하세요.

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>

다음 단계를 시도해 보세요.

  1. save-book 명령어를 사용하여 도서 몇 권 만들기
  2. find-all-books 명령어를 사용하여 검색 실행
  3. 특정 저자의 도서 찾기: find-by-author <author>
  4. 특정 연도 이후에 출판된 도서 찾기: find-by-year-after <year>
  5. 특정 저자 및 연도로 책 찾기: find-by-author-year <author> <year>

9. 웹 인터페이스를 사용하여 Datastore에 저장되는 항목 확인

항목이 Cloud Datastore에 저장되는 방식을 확인하려면 GCP 콘솔로 이동합니다. '도서'를 입력합니다. 필요에 따라 종류 필드에 입력합니다.

5fab21a6c89f45a.png

10. 삭제

삭제하려면 애플리케이션 셸에서 적절한 이름의 remove-all-books 명령어를 사용하여 모든 도서를 삭제합니다.

shell:> remove-all-books

애플리케이션을 종료하려면 종료 명령어와 Ctrl+C를 사용합니다.

11. 축하합니다.

이 Codelab에서는 Cloud Datastore에서 객체를 저장하고 검색할 수 있는 대화형 CLI 애플리케이션을 만들었습니다.

자세히 알아보기

라이선스

이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.