KeyValueTemplate

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

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

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

@Configuration
class MyConfiguration {

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

  @Bean
  public KeyValueAdapter keyValueAdapter() {
    return new MapKeyValueAdapter(ConcurrentHashMap.class);       2
  }
}
1 使用默认 Bean 名称定义一个自定义 KeyValueOperations Bean。有关进一步定制,请参阅 @EnableMapRepositories 的文档和属性。
2 使用存储 ConcurrentHashMap 定义一个自定义 KeyValueAdapter Bean,它由 KeyValueTemplate 使用。

Keyspaces

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

@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 返回 persons keyspace 的所有实体。
2 只返回存储在 persons keyspace 中的 User 类型的元素。

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

Custom KeySpace Annotation

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

组合注释必须继承 @Persistent

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

@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 运行查询。

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

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

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

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

Sorting

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

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 进行排序。