Usage
Spring Data Redis 让你可以轻松实现领域实体,如下面的示例所示:
Spring Data Redis lets you easily implement domain entities, as shown in the following example: .Sample Person Entity
@RedisHash("people")
public class Person {
@Id String id;
String firstname;
String lastname;
Address address;
}
这里有一个非常简单的领域对象。请注意它在其类型上带有 @RedisHash
注释,并且有一个名为 id
的属性,该属性用 org.springframework.data.annotation.Id
进行了注释。这两个项目负责创建用于持久化哈希的实际键。
We have a pretty simple domain object here.
Note that it has a @RedisHash
annotation on its type and a property named id
that is annotated with org.springframework.data.annotation.Id
.
Those two items are responsible for creating the actual key used to persist the hash.
使用 |
Properties annotated with |
为了现在实际上拥有一个负责存储和检索的组件,我们需要定义一个存储库接口,如下面的示例所示:
To now actually have a component responsible for storage and retrieval, we need to define a repository interface, as shown in the following example: .Basic Repository Interface To Persist Person Entities
public interface PersonRepository extends CrudRepository<Person, String> {
}
由于我们的存储库扩展了 CrudRepository
,因此它提供了基本的 CRUD 和查找器操作。我们需要在两者之间粘贴东西的东西是相应的 Spring 配置,如下面的示例所示:
As our repository extends CrudRepository
, it provides basic CRUD and finder operations.
The thing we need in between to glue things together is the corresponding Spring configuration, shown in the following example:
.JavaConfig for Redis Repositories
@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
注入到我们的组件中,如下面的示例所示:
Given the preceding setup, we can inject PersonRepository
into our components, as shown in the following example:
.Access to Person Entities
@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 | Generates a new id if the current value is null or reuses an already set id value and stores properties of type Person inside the Redis Hash with a key that has a pattern of keyspace:id — in this case, it might be people:5d67b7e1-8640-2024-beeb-c666fab4c0e5 . |
2 | Uses the provided id to retrieve the object stored at keyspace:id . |
3 | Counts the total number of entities available within the keyspace, people , defined by @RedisHash on Person . |
4 | Removes the key for the given object from Redis. |
Persisting References
使用 @Reference
标记属性允许存储一个简单的键引用,而不是将值本身复制到哈希中。从 Redis 加载时,引用会自动解析并映射回对象,如下面的示例所示:
Marking properties with @Reference
allows storing a simple key reference instead of copying values into the hash itself.
On loading from Redis, references are resolved automatically and mapped back into the object, as shown in the following example:
_class = org.example.Person
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand
lastname = al’thor
mother = people:a9d4b3a0-50d3-4538-a2fc-f7fc2581ee56 1
1 | Reference stores the whole key (keyspace:id ) of the referenced object. |
当引用对象被保存时,引用对象不会被持久化。您必须单独持久化对引用对象的更改,因为只存储了该引用。不会解析设置在引用类型属性上的索引。
Referenced Objects are not persisted when the referencing object is saved. You must persist changes on referenced objects separately, since only the reference is stored. Indexes set on properties of referenced types are not resolved.
Persisting Partial Updates
在某些情况下,你不必加载和重写整个实体,只需要在其中设置一个新值。最后一个活动时间的会话时间戳可能就是一个这样的场景,你希望更改一个属性。PartialUpdate
让你可以对现有对象定义 set
和 delete
操作,同时负责更新实体本身和索引结构的潜在过期时间。以下示例显示了部分更新:
In some cases, you need not load and rewrite the entire entity just to set a new value within it.
A session timestamp for the last active time might be such a scenario where you want to alter one property.
PartialUpdate
lets you define set
and delete
actions on existing objects while taking care of updating potential expiration times of both the entity itself and index structures.
The following example shows a partial update:
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 | Set the simple firstname property to mat . |
2 | Set the simple 'address.city' property to 'emond’s field' without having to pass in the entire object. This does not work when a custom conversion is registered. |
3 | Remove the age property. |
4 | Set complex address property. |
5 | Set a map of values, which removes the previously existing map and replaces the values with the given ones. |
6 | Automatically update the server expiration time when altering Time To Live. |
更新复杂的对象以及映射(或其他集合)结构需要进一步与 Redis 交互来确定现有值,这意味着可能更快速地重写整个实体。 |
Updating complex objects as well as map (or other collection) structures requires further interaction with Redis to determine existing values, which means that rewriting the entire entity might be faster. |