本指南将引导您完成构建Apache Geode数据管理系统应用程序的过程。

你会建立什么

您将使用Spring Data for Apache Geode来存储和检索POJO。

你需要什么

如何完成本指南

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

从头开始,请继续进行“从Spring Initializr开始”

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

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

从Spring Initializr开始

对于所有Spring应用程序,您应该从Spring Initializr开始。Spring Initializr提供了一种快速的方法来提取应用程序所需的所有依赖关系,并为您完成了许多设置。本示例需要“ Spring for Apache Geode ”依赖项。

以下清单显示了pom.xml使用Maven时的示例文件:

<?xml版本=“ 1.0”编码=“ 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>

    <父母>
        <groupId> org.springframework.boot </ groupId>
        <artifactId> spring-boot-starter-parent </ artifactId>
        <version> 2.4.1 </ version>
    </ parent>

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

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

    <依赖项>
        <依赖性>
            <groupId> org.springframework.boot </ groupId>
            <artifactId> spring-boot-starter </ artifactId>
        </ dependency>
        <依赖性>
            <groupId> org.springframework.data </ groupId>
            <artifactId> spring-data-geode </ artifactId>
        </ dependency>
        <依赖性>
            <groupId> org.springframework.shell </ groupId>
            <artifactId>弹簧壳</ artifactId>
            <version> $ {spring-shell.version} </ version>
            <scope>运行时</ scope>
        </ dependency>
        <依赖性>
            <groupId> org.projectlombok </ groupId>
            <artifactId>龙目岛</ artifactId>
        </ dependency>
    </ dependencies>

    <内部版本>
        <插件>
            <插件>
                <groupId> org.springframework.boot </ groupId>
                <artifactId> spring-boot-maven-plugin </ artifactId>
            </ plugin>
        </ plugins>
    </ build>

</ project>

以下清单显示了build.gradle使用Gradle时的示例文件:

插件{
    id'org.springframework.boot'版本'2.4.1'
    id'io.spring.dependency-management'版本'1.0.8.RELEASE'
    id“ io.freefair.lombok”版本“ 5.3.0”
    id'java'
}

套用外挂程式:'eclipse'
套用外挂程式:'idea'

组=“ org.springframework”
版本=“ 0.1.0”
sourceCompatibility = 1.8
targetCompatibility = 1.8

储存库{
    mavenCentral()
}

依赖项{
    实现“ org.springframework.boot:spring-boot-starter”
    实现“ org.springframework.data:spring-data-geode”
    实现“ org.projectlombok:lombok”
    runtimeonly只有“ org.springframework.shell:spring-shell:1.2.0.RELEASE”
}

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

定义一个简单的实体

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

Apache Geode是一个键/值存储,而Region则实现了该java.util.concurrent.ConcurrentMap接口。尽管您可以将Region视为a java.util.Map,但它比简单的Java要复杂得多,Map因为在该Region内分布,复制和管理了数据。

在此示例中,Person仅使用一些注释将对象存储在Apache Geode(一个区域)中。

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")。当Apache Geode存储此类的实例时,将在“人员”区域内创建一个新条目。此类也用标记该name字段@Id。这表示用于标识和跟踪PersonApache Geode内部数据的标识符。本质上,带@Id注释的字段(例如name)是键,Person实例是键/值条目中的值。Apache Geode中没有自动生成密钥的功能,因此您必须先设置ID(即name),然后再将实体持久化到Apache Geode。

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

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

创建简单的查询

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

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

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从接口弹簧数据共享和指定类型的一般类型参数两者的值和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 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")
@EnableEntityDefinedRegions(
  basePackageClasses = Person.class,
  clientRegionShortcut = ClientRegionShortcut.LOCAL
)
@EnableGemfireRepositories
public class Application {

  public static void main(String[] args) {
    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 Apache Geode...");

      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 Apache Geode按类型扫描不同的根包,以查找特定于应用程序的存储库扩展。

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

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

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

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

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

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

该应用程序将自动装配PersonRepository您刚刚定义的实例。用于Apache Geode的Spring Data将动态创建一个实现该接口的具体类,并插入所需的查询代码以满足接口的义务。该方法使用此存储库实例run()来演示功能。

存储和获取数据

在本指南中,您将创建三个本地Person对象AliceBaby BobTeen Carol。最初,它们仅存在于内存中。创建它们之后,您必须将它们保存到Apache Geode。

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

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

建立可执行的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文件

您应该看到类似以下的内容(以及其他类似查询的内容):

在与{apache-geode-name}链接之前...
	爱丽丝40岁。
	小鲍勃1岁。
	Teen Carol是13岁。
通过名称查找每个人...
	爱丽丝40岁。
	小鲍勃1岁。
	Teen Carol是13岁。
成人(18岁以上):
	爱丽丝40岁。
婴儿(5岁以下):
	小鲍勃1岁。
青少年(12至20岁之间):
	Teen Carol是13岁。

概括

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

也可以看看

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

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

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