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

你会建立什么

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

你需要什么

如何完成本指南

像大多数Spring 入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都可以使用工作代码。

从头开始 ,请继续使用Gradle构建

跳过基础知识 ,请执行以下操作:

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

用Gradle构建

用Gradle构建

首先,您设置一个基本的构建脚本。在使用Spring构建应用程序时,可以使用任何喜欢的构建系统,但是此处包含使用GradleMaven所需的代码。如果您都不熟悉,请参阅使用Gradle 构建Java项目使用Maven构建Java项目

创建目录结构

在您选择的项目目录中,创建以下子目录结构;例如, mkdir -p src/main/java/hello在* nix系统上:

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

创建一个Gradle构建文件

build.gradle

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

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

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

sourceCompatibility = 1.8
targetCompatibility = 1.8

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

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

dependencies {
    compile("org.springframework.boot:spring-boot-starter") {
        exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
    }
    compile("org.springframework.data:spring-data-gemfire")
    compile("org.projectlombok:lombok")
    runtime("org.springframework.shell:spring-shell:1.2.0.RELEASE")
}

Spring Boot gradle插件提供了许多方便的功能:

  • 它收集类路径上的所有jar,并构建一个可运行的单个“über-jar”,这使执行和传输服务更加方便。

  • 它搜索public static void main()标记为可运行类的方法。

  • 它提供了一个内置的依赖项解析器,用于设置版本号以匹配Spring Boot依赖项 。您可以覆盖所需的任何版本,但是它将默认为Boot选择的一组版本。

用Maven构建

用Maven构建

首先,您设置一个基本的构建脚本。使用Spring构建应用程序时,可以使用任何喜欢的构建系统,但是此处包含了使用Maven所需的代码。如果您不熟悉Maven,请参阅使用Maven 构建Java项目

创建目录结构

在您选择的项目目录中,创建以下子目录结构;例如, mkdir -p src/main/java/hello在* nix系统上:

└── 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 https://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>2.1.6.RELEASE</version>
    </parent>

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

    <properties>
        <spring-shell.version>1.2.0.RELEASE</spring-shell.version>
    </properties>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </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>

</project>

Spring Boot Maven插件提供了许多方便的功能:

  • 它收集类路径上的所有jar,并构建一个可运行的单个“über-jar”,这使执行和传输服务更加方便。

  • 它搜索public static void main()标记为可运行类的方法。

  • 它提供了一个内置的依赖项解析器,用于设置版本号以匹配Spring Boot依赖项 。您可以覆盖所需的任何版本,但是它将默认为Boot选择的一组版本。

使用您的IDE进行构建

使用您的IDE进行构建

定义一个简单的实体

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

Pivotal GemFire是键/值存储,而Region则实现了java.util.concurrent.ConcurrentMap接口。虽然您可以将Region视为java.util.Map ,它比简单的Java要复杂得多Map给定的数据在区域内进行分发,复制和总体管理。

在此示例中,您存储Person仅使用一些注释的Pivotal GemFire(区域)中的对象。

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 years old", getName(), getAge());
    }
}

在这里你有一个Person有两个领域的课程, nameage 。您还具有一个持久的构造函数,用于在创建新实例时填充实体。该类使用Project Lombok简化实现。

注意,该类用注释@Region("People") 。当Pivotal GemFire存储此类的实例时,将在“人员”区域中创建一个新条目。此类也标志着name场与@Id 。这表示用于识别和跟踪Person Pivotal GemFire内部的数据。本质上, @Id带注释的字段(例如name )是关键, Person instance是键/值条目中的值。Pivotal GemFire没有自动生成密钥的功能,因此您必须设置ID(即name ),然后将实体保留到Pivotal GemFire。

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

被覆盖toString()方法将打印出该人的姓名和年龄。

创建简单的查询

Pivotal GemFire的Spring数据专注于使用Spring在Pivotal GemFire中存储和访问数据。它还从Spring Data Commons项目继承了强大的功能,例如导出查询的功能。本质上,您不必学习Pivotal GemFire(OQL)的查询语言;您只需编写一些方法,框架即可为您编写查询。

要查看其工作原理,请创建一个查询接口Person存储在Pivotal GemFire中的对象。

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扩展CrudRepository Spring Data Commons的接口,并为存储库使用的值和id(键)指定通用类型参数的类型,即PersonString , 分别。该界面开箱即用,具有许多操作,包括基本的CRUD(CREATE,READ UPDATE,DELETE)和简单的查询(例如, findById(..) )数据访问操作。

您可以根据需要定义其他查询,只需声明它们的方法签名即可。在这种情况下,您添加findByName ,实际上是搜索类型为Person并找到一个匹配name

您还有:

  • findByAgeGreaterThan寻找一定年龄以上的人

  • findByAgeLessThan寻找某个年龄以下的人

  • findByAgeGreaterThanAndAgeLessThan寻找某个年龄段的人

让我们进行连线,看看它是什么样子!

创建一个应用程序类

在这里,您将创建一个具有所有组件的Application类。

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.client.ClientRegionShortcut;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

@SpringBootApplication
@ClientCacheApplication(name = "AccessingDataGemFireApplication", logLevel = "error")
@EnableEntityDefinedRegions(basePackageClasses = Person.class,
  clientRegionShortcut = ClientRegionShortcut.LOCAL)
@EnableGemfireRepositories
public class Application {

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

    @Bean
    ApplicationRunner run(PersonRepository personRepository) {

        return args -> {

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

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

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

            System.out.println("Saving Alice, Bob and Carol to Pivotal 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 Repository接口之一的接口。用它的basePackageClasses = MyRepository.class安全地告诉Spring Data for Pivotal GemFire按类型扫描不同的根包,以查找特定于应用程序的存储库扩展。

需要包含1个或多个Regions的Pivotal GemFire缓存来存储所有数据。为此,您可以使用Spring Data中的 1种作为Pivotal GemFire方便的基于配置的注释: @ClientCacheApplication@PeerCacheApplication or `@CacheServerApplication

Pivotal GemFire支持不同的缓存拓扑,例如客户端/服务器,对等(p2p)甚至WAN安排。在p2p中,对等缓存实例嵌入在应用程序中,您的应用程序将能够以对等缓存成员的身份参与集群。但是,您的应用程序受群集中对等成员的所有限制,因此,它不像客户端/服务器拓扑结构那样普遍使用。

在我们的情况下,我们将使用@ClientCacheApplication创建“客户端”缓存实例,该实例具有连接到服务器集群并与之通信的能力。但是,为了简单起见,客户端只会使用LOCAL客户端区域,而无需设置或运行任何服务器。

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

现在,记住您如何标记Person使用SDG映射注释存储在称为“人”的区域中, @Region("People") ?您可以在此处使用ClientRegionFactoryBean Bean定义。您需要注入刚定义的缓存的实例,同时将其命名为“ People ”。

Pivotal GemFire缓存实例(对等实体或客户端)只是用于存储数据的Regions的容器。您可以将高速缓存视为RDBMS中的架构,将区域视为表。但是,缓存还执行其他管理功能来控制和管理您的所有区域。
类型是 ,匹配密钥类型( String )的值类型( Person )。

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

该应用程序自动关联以下对象的实例PersonRepository您刚刚定义的用于Pivotal GemFire的Spring Data将动态创建一个实现该接口的具体类,并插入所需的查询代码以满足接口的职责。该存储库实例是run()演示功能的方法。

存储和获取数据

在本指南中,您将创建三个本地Person对象, 爱丽丝(Alice)小鲍勃Baby Bob )和青少年卡罗尔Teen Carol) 。最初,它们仅存在于内存中。创建它们之后,您必须将它们保存到Pivotal GemFire。

现在,您运行几个查询。第一个按名称查找所有人。然后,您使用年龄属性执行少量查询以查找成人,婴儿和青少年。打开日志记录后,您可以看到Spring Data for Pivotal GemFire代表您编写的查询。

改变@ClientCacheApplication注解logLevel属性为“ config ”以查看由SDG生成的Pivotal GemFire OQL查询。因为查询方法(例如findByName )标注为SDG @Trace注释,这将打开Pivotal GemFire的OQL查询跟踪(查询级日志记录),该查询向您显示生成的OQL,执行时间,查询是否使用了任何Pivotal GemFire索引来收集结果以及该查询返回的行数。查询。

构建可执行的JAR

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

如果您使用Gradle,则可以使用./gradlew bootRun 。或者,您可以通过使用以下命令构建JAR文件: ./gradlew build然后运行JAR文件,如下所示:

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

如果使用Maven,则可以通过使用以下命令运行应用程序./mvnw spring-boot:run 。或者,您可以使用以下命令构建JAR文件: ./mvnw clean package然后运行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.

摘要

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

也可以看看

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

是否要编写新指南或为现有指南做出贡献?查看我们的贡献准则

所有指南均以代码的ASLv2许可证和写作的Attribution,NoDerivatives创作共用许可证发布