原文:Accessing Data with GemFire,译者:dejunyu,校对:

本指南将指导您完成使用GemFire的数据结构构建应用程序的过程。

你会建立什么

您将使用功能强大的Spring Data GemFire库来存储和检索POJO

你需要什么

如何完成本指南

与大多数“ 入门指南 ”一样,你可以从头开始,完成每一步,也可以绕过已经熟悉的基本设置步骤。无论哪种方式,你都会得到可以成功运行的代码。

从头开始,请跳转到使用 Gradle构建

跳过基本操作,请执行以下操作:

  • 下载 并解压缩本指南的源代码库,或使用 Git 克隆它:git clone https://github.com/spring-guides/gs-accessing-data-gemfire.git
  • cd进入 gs-accessing-data-gemfire/initial
  • 跳转到定义的一个简单的实体

完成后,你可以根据代码检查结果 gs-accessing-data-gemfire/complete

使用 Gradle 构建

第一步,建立基本的构建脚本(build script)。 当使用 Spring 构建 apps 的时候,几乎可以使用任何你喜欢的构建工具, 但是此指南只介绍了如何使用 Gradle 和 Maven 来构建目标 app。如果这两个工具你都不熟悉,请参考 Building Java Projects with GradleBuilding Java Projects with Maven

创建目录结构

在你选择的项目目录中,创建以下子目录结构。例如,在 *nix 系统中使用命令 mkdir -p src/main/java/hello 来创建该目录结构。

└── src
    └── main
        └── java
            └── hello

创建一个Gradle构建文件

以下是 初始化的Gradle构建文件

build.gradle

buildscript {
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/libs-release" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.9.RELEASE")
    }
}

plugins {
    id "io.spring.dependency-management" version "1.0.3.RELEASE"
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

sourceCompatibility = 1.8
targetCompatibility = 1.8

jar {
    baseName = 'gs-accessing-data-gemfire'
    version = '0.1.0'
}

repositories {
    mavenCentral()
    maven { url "https://repo.spring.io/libs-release" }
}

dependencyManagement {
    imports {
        mavenBom 'org.springframework:spring-framework-bom:5.0.1.RELEASE'
        mavenBom 'org.springframework.data:spring-data-releasetrain:Kay-SR1'
    }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter")
    compile("org.springframework.data:spring-data-gemfire")
    compile("org.projectlombok:lombok:1.16.18")
    runtime("org.springframework.shell:spring-shell:1.2.0.RELEASE")
}

Spring Boot Gradle plugin 提供了许多方便的功能:

  • 它收集类路径上的所有jar,并构建一个可运行的“über-jar”,这使得执行和传输服务更加方便。
  • 搜索 public static void main() ,并对该可执行类进行标记。
  • 提供了一个内置的依赖解析功能,该功能将依赖的版本与 Spring Boot dependencies 相匹配。用户可以按照需求覆盖依赖(dependency)的任何版本号,但是默认版本号是 Spring Boot中已经选择好的版本号的集合。

使用 Maven 构建应用程序

第一步,建立基本构建脚本(build script)。 当使用Spring构建apps的时候,几乎可以使用任何你喜欢的构建工具, 但是此部分只介绍了如何使用 Maven 来构建目标app。如果你不熟悉这个工具,请参考 Building Java Projects with Maven

创建目录结构

在你选定的工程目录中,创建如下的子目录结构。 例如,在 *nix 中使用命令 mkdir -p src/main/java/hello 来创建该目录结构。

└── src
    └── main
        └── java
            └── hello

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <groupId>org.springframework</groupId>
    <artifactId>gs-accessing-data-gemfire</artifactId>
    <version>0.1.0</version>

    <properties>
        <java.version>1.8</java.version>
        <spring.version>5.0.1.RELEASE</spring.version>
        <spring-data-releasetrain.version>Kay-SR1</spring-data-releasetrain.version>
        <spring-shell.version>1.2.0.RELEASE</spring-shell.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-gemfire</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.shell</groupId>
            <artifactId>spring-shell</artifactId>
            <version>${spring-shell.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>

</project>
  • Spring Boot Maven plugin 提供了许多方便的功能:
    • 将 classpath 中的所有 jar 文件集中起来,构建成单独的可运行的 “über-jar”, 这使得服务的运行和转移更加便捷。
    • 搜索 public static void main() ,并对该可执行类进行标记。
    • 提供了一个内置的依赖解析功能,该功能将依赖的版本与 Spring Boot dependencies 相匹配。用户可以按照需求覆盖依赖(dependency)的任何版本号,但是默认版本号是 Spring Boot中已经选择好的版本号的集合。

使用IDE构建

定义一个简单的实体

Pivotal GemFire是一个将数据映射到区域的内存数据网格(IMDG)。 可以配置分布式区域,用于跨群集中的多个节点分区和复制数据。 但是,在本指南中,您将使用本地区域,因此您不必另外设置任何内容,例如整个服务器群集。

GemFire是一个键/值存储区,一个Region实现了java.util.concurrent.ConcurrentMap接口。 虽然你可以像一个java.util.Map那样对待一个Region,但它比一个简单的Java Map要复杂得多,因为数据在这个Region内被分配,复制和管理。

在这个例子中,你只用几个注释就可以把Person对象存储在GemFire(一个Region)中。

src/main/java/hello/Person.java

package hello;

import java.io.Serializable;

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.gemfire.mapping.annotation.Region;

import lombok.Getter;

@Region(value = "People")
public class Person implements Serializable {

    @Id
    @Getter
    private final String name;

    @Getter
    private final int age;

    @PersistenceConstructor
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return String.format("%s is %d year(s) old", name, age);
    }
}

在这里你有一个Person类,有两个字段,nameage。 在创建新实例时,您也有一个持久的构造函数来填充实体。 该类使用Project Lombok 来简化实施。

注意这个类是用@Region(“People”)注解的。 当GemFire存储这个类的实例时,会在“People”区域内创建一个新条目。 这个类也用@Id标记name字段。 这表示用于识别和跟踪GemFire中的Person数据的标识符。 本质上,@Id带注释的字段(例如name)是键,Person实例是键/值条目中的值。 在GemFire中没有自动生成密钥,因此您必须在将实体持久化到GemFire之前设置id(即name)。

下一个重要的部分是这个人的年龄。 在本指南的后面,您将使用它来形成一些查询。

重写的toString()方法将打印出人的姓名和年龄。

创建简单的查询

Spring Data GemFire专注于存储和访问GemFire中的数据。 它还继承了Spring Data Commons项目的强大功能,如派生查询的能力。 本质上,您不必学习GemFire(OQL)的查询语言; 您可以简单地编写一些方法,查询是由框架为您编写的。

要查看这是如何工作的,请创建一个查询存储在GemFire中的Person对象的接口。

src/main/java/hello/PersonRepository.java

package hello;

import org.springframework.data.gemfire.repository.query.annotation.Trace;
import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, String> {

    @Trace
    Person findByName(String name);

    @Trace
    Iterable<Person> findByAgeGreaterThan(int age);

    @Trace
    Iterable<Person> findByAgeLessThan(int age);

    @Trace
    Iterable<Person> findByAgeGreaterThanAndAgeLessThan(int greaterThanAge, int lessThanAge);

}

PersonRepository扩展了Spring Data Commons中的CrudRepository接口,并分别为存储库使用的值和id(键)指定泛型类型参数的类型,即PersonString。 开箱即用,这个接口带有许多操作,包括基本的CRUD(CREATE,READ UPDATE,DELETE)和简单的查询(例如findById(..))数据访问操作。

您可以通过简单地声明其方法签名来定义其他查询。 在这种情况下,您添加findByName,它本质上搜索Person类型的对象并找到与name匹配的对象。

你也有:

  • findByAgeGreaterThan找到超过一定年龄的人
  • findByAgeLessThan找到一定年龄以下的人
  • findByAgeGreaterThanAndAgeLessThan找到某个年龄段的人

让我们把它连接起来,看看它是什么样的!

创建一个应用程序类

在这里你创建一个包含所有组件的应用程序类。

src/main/java/hello/Application.java

package hello;

import static java.util.Arrays.asList;
import static java.util.stream.StreamSupport.stream;

import java.io.IOException;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

@ClientCacheApplication(name = "DataGemFireApplication", logLevel = "error")
@EnableGemfireRepositories
public class Application {

    public static void main(String[] args) throws IOException {
        SpringApplication.run(Application.class, args);
    }

    @Bean("People")
    public ClientRegionFactoryBean<String, Person> peopleRegion(GemFireCache gemfireCache) {

        ClientRegionFactoryBean<String, Person> peopleRegion = new ClientRegionFactoryBean<>();

        peopleRegion.setCache(gemfireCache);
        peopleRegion.setClose(false);
        peopleRegion.setShortcut(ClientRegionShortcut.LOCAL);

        return peopleRegion;
    }

    @Bean
    ApplicationRunner run(PersonRepository personRepository) {

        return args -> {

            Person alice = new Person("Alice", 40);
            Person bob = new Person("Baby Bob", 1);
            Person carol = new Person("Teen Carol", 13);

            System.out.println("Before accessing data in GemFire...");

            asList(alice, bob, carol).forEach(person -> System.out.println("\t" + person));

            System.out.println("Save Alice, Bob and Carol to GemFire...");

            personRepository.save(alice);
            personRepository.save(bob);
            personRepository.save(carol);

            System.out.println("Lookup each person by name...");

            asList(alice.getName(), bob.getName(), carol.getName())
              .forEach(name -> System.out.println("\t" + personRepository.findByName(name)));

            System.out.println("Query adults (over 18):");

            stream(personRepository.findByAgeGreaterThan(18).spliterator(), false)
              .forEach(person -> System.out.println("\t" + person));

            System.out.println("Query babies (less than 5):");

            stream(personRepository.findByAgeLessThan(5).spliterator(), false)
              .forEach(person -> System.out.println("\t" + person));

            System.out.println("Query teens (between 12 and 20):");

            stream(personRepository.findByAgeGreaterThanAndAgeLessThan(12, 20).spliterator(), false)
              .forEach(person -> System.out.println("\t" + person));
        };
    }
}

在配置中,您需要添加@EnableGemfireRepositories注释。

  • 默认情况下,@EnableGemfireRepositories将会扫描当前包中的任何扩展Spring Data接口的接口。使用它的basePackageClasses = MyRepository.class安全地告诉Spring Data GemFire通过类型来扫描不同的根包,以获取特定于应用程序的Repository扩展。

包含一个或多个区域的GemFire缓存需要存储所有的数据。为此,您使用Spring Data GemFire的基于配置的便捷注释:@ClientCacheApplication@PeerCacheApplication@CacheServerApplication

GemFire支持不同的缓存拓扑结构,如客户端/服务器,点对点(p2p)甚至WAN安排。在p2p中,对等缓存实例嵌入在应用程序中,您的应用程序将有能力作为对等缓存成员加入群集。但是,您的应用程序受限于在集群中作为对等成员的所有约束,所以这不像通常所说的客户端/服务器拓扑那样。

在我们的例子中,我们将使用@ClientCacheApplication来创建一个“客户端”缓存实例,它能够连接到一组服务器并与之通信。但是,为了简单起见,客户端只需使用LOCAL客户端区域在本地存储数据,而不需要设置或运行任何服务器。

Spring建议生产Pivotal GemFire的企业版,您可以在群集中的多个节点上创建分布式缓存和区域。 或者,您也可以使用开源版本Apache Geode,并从Apache Geode社区获得支持。

现在,请记住如何使用SDG映射注释@Region(“People”)Person标记为存储在名为“People”的Region中? 您可以在这里使用ClientRegionFactoryBean <String,Person> bean定义来定义该区域。 你需要注入一个你刚定义的缓存实例,同时命名为“People”。

GemFire缓存实例(无论是对等体还是客户机)只是存储数据的区域的容器。 您可以将RDBMS和Regions中的缓存视为表中的模式。 但是,缓存还执行其他管理功能来控制和管理您的所有区域。

类型是<String,Person>,将键类型(String)与值类型(Person)进行匹配。

public static void main方法使用Spring Boot的SpringApplication.run()来启动应用程序并调用ApplicationRunner(另一个bean定义),该应用程序使用应用程序的Spring Data Repository在GemFire上执行数据访问操作。

应用程序自动装载您刚刚定义的PersonRepository实例。 Spring Data GemFire将动态创建一个实现此接口的具体类,并插入所需的查询代码以满足接口的义务。 这个Repository实例是run()方法用来演示这个功能的。

存储和获取数据

在本指南中,您将创建三个本地Person对象,Alice,Baby BobTeen Carol。 最初,他们只存在于记忆中。 创建它们之后,你必须将它们保存到GemFire。

现在你运行几个查询。 第一个按名字查找每个人。 然后执行一些查询来查找成年人,婴儿和青少年,所有这些都使用年龄属性。 随着日志的出现,你可以看到Spring Data GemFire为你写的查询。

@ClientCacheApplication注释logLevel属性更改为“config”以查看由SDG生成的GemFire OQL查询。 由于查询方法(例如findByName)是使用SDG的@Trace注释进行注释的,因此会启用GemFire的OQL查询跟踪(查询级别日志记录),该查询会显示生成的OQL,执行时间以及查询是否使用了任何GemFire索引 收集结果以及查询返回的行数。

构建一个可执行的JAR

您可以使用Gradle或Maven从命令行运行应用程序。 或者,您可以构建一个包含所有必需的依赖项,类和资源的可执行JAR文件,然后运行该文件。 这使得在整个开发生命周期内跨越不同的环境等等,将服务作为应用程序发布,版本化和部署变得容易。

如果您正在使用Gradle,则可以使用./gradlew bootRun运行该应用程序。 或者您可以使用./gradlew build生成JAR文件。 然后你可以运行JAR文件:

java -jar build/libs/gs-accessing-data-gemfire-0.1.0.jar

如果您正在使用Maven,则可以使用./mvnw spring-boot:run来运行该应用程序。 或者你也可以使用./mvnw clean package建立JAR文件。 然后你可以运行JAR文件:

java -jar target/gs-accessing-data-gemfire-0.1.0.jar

上面的过程将创建一个可运行的JAR。 您也可以选择构建一个经典的WAR文件。 你应该看到像这样的东西(以及其他的东西,如查询):

Before linking up with GemFire...
    Alice is 40 years old.
    Baby Bob is 1 years old.
    Teen Carol is 13 years old.
Lookup each person by name...
    Alice is 40 years old.
    Baby Bob is 1 years old.
    Teen Carol is 13 years old.
Adults (over 18):
    Alice is 40 years old.
Babies (less than 5):
    Baby Bob is 1 years old.
Teens (between 12 and 20):
    Teen Carol is 13 years old.

概要

恭喜! 您设置了一个GemFire缓存客户端,存储简单的实体,并开发了快速查询。

也可以看看

以下指南也可能有所帮助:

想写一个新的指南或贡献一个现有的?查看我们的贡献指南

本文由spring4all.com翻译小分队创作,采用知识共享-署名-非商业性使用-相同方式共享 4.0 国际 许可 协议进行许可。

评论 抢沙发

请登录后发表评论

    暂无评论内容