KeyValueTemplate

在基本形态中,KeyValueTemplate 使用 MapAdapter,它封装了 ConcurrentHashMap,并使用 Spring Expression Language 运行查询和排序。

In its very basic shape, the KeyValueTemplate uses a MapAdapter that wraps a ConcurrentHashMap and that uses Spring Expression Language to run queries and sorting.

在数据存储和检索方面,已使用的 KeyValueAdapter 将履行繁重的任务。数据结构将影响性能和多线程行为。

The used KeyValueAdapter does the heavy lifting when it comes to storing and retrieving data. The data structure influences performance and multi-threading behavior.

你可以使用其他类型或使用一些值对适配器进行预初始化,你可以通过对 MapKeyValueAdapter 使用各种构造函数来执行此操作,如下面的示例所示:

You can use a different type or pre-initialize the adapter with some values, and you can do so by using various constructors on MapKeyValueAdapter, as the following example shows:

@Configuration
class MyConfiguration {

  @Bean
  public KeyValueOperations mapKeyValueTemplate() {               1
    return new KeyValueTemplate(keyValueAdapter());
  }

  @Bean
  public KeyValueAdapter keyValueAdapter() {
    return new MapKeyValueAdapter(ConcurrentHashMap.class);       2
  }
}
1 Defines a custom KeyValueOperations bean using the default bean name. See documentation and properties of @EnableMapRepositories for further customization.
2 Defines a custom KeyValueAdapter bean using a ConcurrentHashMap as storage that is used by KeyValueTemplate.

Keyspaces

下面的示例显示了用于存储库 Person 对象的键空间:

The following example shows a keyspace for a repository of Person objects:

@KeySpace("persons")
class Person {

  @Id String id;
  String firstname;
  String lastname;
}

class User extends Person {
  String username;
}

template.findAllOf(Person.class); 1
template.findAllOf(User.class);   2
1 Returns all entities for the persons keyspace.
2 Returns only elements of type User stored in persons keyspace.

@KeySpace 支持 SpEL 表达式,允许动态密钥空间配置。

@KeySpace supports SpEL expressions allowing dynamic keyspace configuration.

Custom KeySpace Annotation

你可以在其中一个属性上添加 @AliasFor 注释,为域中心化使用方式编写自己的 KeySpace 注释。

You can compose your own KeySpace annotations for a more domain-centric usage by annotating one of the attributes with @AliasFor.

组合注释必须继承 @Persistent

The composed annotation must inherit @Persistent.

以下示例展示了一个自定义 @KeySpace 注释:

The following example shows a custom @KeySpace annotation:

@KeySpace
@Persistent
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
static @interface CacheCentricAnnotation {

  @AliasFor(annotation = KeySpace.class, attribute = "value")
  String cacheRegion() default "";
}

@CacheCentricAnnotation(cacheRegion = "customers")
class Customer {
  //...
}

Querying

查询的运行由 QueryEngine 管理。如前所述,你可以指示 KeyValueAdapter 使用允许访问本机功能的实施特定 QueryEngine。在未进一步自定义的情况下,可以使用 SpELQueryEngine 运行查询。

Running queries is managed by a QueryEngine. As mentioned earlier, you can instruct the KeyValueAdapter to use an implementation-specific QueryEngine that allows access to native functionality. When used without further customization, queries can be run by using SpELQueryEngine.

出于性能原因,我们强烈建议至少使用 Spring Framework 4.1.2 或更好版本来利用 compiled SpEL Expressions。(“SpEL” 是"`Spring Expression Language`" 的缩写。)您可以使用`-Dspring.expression.compiler.mode=IMMEDIATE` 开关启用它。

For performance reasons, we highly recommend to have at least Spring Framework 4.1.2 or better to make use of compiled SpEL Expressions. (“SpEL” is short for “Spring Expression Language”.) You can use the -Dspring.expression.compiler.mode=IMMEDIATE switch to enable it.

以下示例展示了一个使用 SpEL 的查询:

The following example shows a query that uses the SpEL:

KeyValueQuery<String> query = new KeyValueQuery<String>("lastname == 'targaryen'");
List<Person> targaryens = template.find(query, Person.class);

在使用 SpEL 时,您必须提供 getter 和 setter 来查询属性。

You must have getters and setters present to query properties when you use SpEL.

Sorting

实体可能已经按照某些分类方式进行存储,但不必一定是这样,这取决于适配器提供的存储实现。再说一遍,底层 QueryEngine 能够执行分类操作。在未进一步自定义的情况下,分类是使用从 Sort 子句中提取的 SpelPropertyComparator 来完成的。以下示例展示了一个带 Sort 子句的查询:

Depending on the store implementation provided by the adapter, entities might already be stored in some sorted way but do not necessarily have to be.Again, the underlying QueryEngine is capable of performing sort operations. When used without further customization, sorting is done by using a SpelPropertyComparator extracted from the Sort clause.The following example shows a query with a Sort clause:

KeyValueQuery<String> query = new KeyValueQuery<String>("lastname == 'baratheon'");
query.setSort(Sort.by(DESC, "age"));
List<Person> targaryens = template.find(query, Person.class);

请注意,您需要提供 getter 和 setter 来使用 SpEL 进行排序。

Please note that you need to have getters and setters present to sort using SpEL.