|
对于最新的稳定版本,请使用 Spring Data Redis 4.0.4! |
用法
Spring Data Redis 让您可以轻松实现领域实体,如下例所示:
示例 1. 示例 Person 实体
@RedisHash("people")
public class Person {
@Id String id;
String firstname;
String lastname;
Address address;
}
我们这里有一个相当简单的领域对象。
请注意,它的类型上有一个 @RedisHash 注解,并且有一个名为 id 的属性,该属性使用了 org.springframework.data.annotation.Id 注解。
这两项共同决定了用于持久化哈希的实际键(key)。
使用 @Id 注解的属性以及名为 id 的属性被视为标识符属性。
带有注解的属性优先于其他属性。 |
为了真正拥有一个负责存储和检索的组件,我们需要定义一个仓库接口,如下例所示:
示例 2. 用于持久化 Person 实体的基本 Repository 接口
public interface PersonRepository extends CrudRepository<Person, String> {
}
由于我们的仓库接口扩展了 CrudRepository,因此它提供了基本的 CRUD 操作和查找操作。
在中间将这些组件连接在一起所需的就是相应的 Spring 配置,如下例所示:
示例 3. Redis 仓库的 JavaConfig 配置
@Configuration
@EnableRedisRepositories
public class ApplicationConfig {
@Bean
public RedisConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
根据上述配置,我们可以将 PersonRepository 注入到我们的组件中,如下例所示:
示例 4. 访问 Person 实体
@Autowired PersonRepository repo;
public void basicCrudOperations() {
Person rand = new Person("rand", "al'thor");
rand.setAddress(new Address("emond's field", "andor"));
repo.save(rand); (1)
repo.findOne(rand.getId()); (2)
repo.count(); (3)
repo.delete(rand); (4)
}
| 1 | 如果当前值为 id,则生成一个新的 null;否则复用已设置的 id 值,并将类型为 Person 的属性存储在 Redis 哈希中,其键采用 keyspace:id 的模式——在此例中,键可能是 people:5d67b7e1-8640-present-beeb-c666fab4c0e5。 |
| 2 | 使用提供的 id 来检索存储在 keyspace:id 处的对象。 |
| 3 | 统计在 people 类上通过 @RedisHash 注解定义的键空间(keyspace)Person 中可用实体的总数。 |
| 4 | 从 Redis 中移除给定对象的键。 |
持久化引用
使用 @Reference 注解标记属性,可以存储一个简单的键引用,而不是将值直接复制到哈希本身中。
从 Redis 加载时,引用会自动解析并重新映射回对象,如下例所示:
示例 5. 属性引用示例
_class = org.example.Person
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand
lastname = al’thor
mother = people:a9d4b3a0-50d3-4538-a2fc-f7fc2581ee56 (1)
| 1 | 引用存储所引用对象的完整键(keyspace:id)。 |
| 引用的对象在保存引用对象时不会被持久化。 您必须单独持久化被引用对象上的更改,因为仅存储了引用。 在引用类型属性上设置的索引不会被解析。 |
持久化部分更新
在某些情况下,你无需加载并重写整个实体,仅为了设置其中的一个新值。
例如,更新会话的最后活跃时间戳可能就属于这种只需修改一个属性的场景。
PartialUpdate 允许你对现有对象定义 set 和 delete 操作,同时自动处理实体本身及其索引结构的潜在过期时间更新。
以下示例展示了一次部分更新:
示例6. 部分更新示例
PartialUpdate<Person> update = new PartialUpdate<Person>("e2c7dcee", Person.class)
.set("firstname", "mat") (1)
.set("address.city", "emond's field") (2)
.del("age"); (3)
template.update(update);
update = new PartialUpdate<Person>("e2c7dcee", Person.class)
.set("address", new Address("caemlyn", "andor")) (4)
.set("attributes", singletonMap("eye-color", "grey")); (5)
template.update(update);
update = new PartialUpdate<Person>("e2c7dcee", Person.class)
.refreshTtl(true); (6)
.set("expiration", 1000);
template.update(update);
| 1 | 将简单的 firstname 属性设置为 mat。 |
| 2 | 将简单的 'address.city' 属性设置为 'emond’s field',而无需传入整个对象。 当注册了自定义转换器时,此方法无效。 |
| 3 | 移除 age 属性。 |
| 4 | 设置复杂的 address 属性。 |
| 5 | 设置一个值的映射(Map),该操作会移除先前存在的映射,并用给定的值替换。 |
| 6 | 在修改生存时间(Time To Live)时,自动更新服务器的过期时间。 |
| 更新复杂对象以及映射(或其他集合)结构需要与 Redis 进行进一步交互以确定现有值,这意味着重写整个实体可能会更快。 |