使用说明
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
注解。这两个部分负责创建用于持久化哈希的实际键。
使用 @Id
注解的属性以及命名为 id
的属性被视为标识符属性。带有注解的属性优先于其他属性。
现在,为了真正拥有一个负责存储和检索的组件,我们需要定义一个仓库接口,如下例所示:
示例 2. 用于持久化 Person 实体的基本仓库接口
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
}
如果当前值为
null
,则生成一个新的id
,或者重用已设置的id
值,并将Person
类型的属性存储在以keyspace:id
模式为键的 Redis Hash 中——在这种情况下,键可能是people:5d67b7e1-8640-2025-beeb-c666fab4c0e5
。使用提供的
id
检索存储在keyspace:id
中的对象。计算由
Person
上的@RedisHash
定义的键空间people
中可用的实体总数。从 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>
引用存储被引用对象的完整键 (
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);
将简单的
firstname
属性设置为mat
。在不传递整个对象的情况下,将简单的
address.city
属性设置为emond’s field
。当注册了自定义转换时,此操作无效。移除
age
属性。设置复杂的
address
属性。设置值的映射,这会移除之前存在的映射,并用给定的值替换。
在更改 Time To Live 时自动更新服务器过期时间。
更新复杂对象以及映射(或其他集合)结构需要进一步与 Redis 交互以确定现有值,这意味着重写整个实体可能更快。