Skip to content

Commit c1476b7

Browse files
committed
DATAREDIS-503 - Polishing.
Rename ConvertingHashMapper to ObjectHashMapper. Add fromHash with type to avoid casting. Add JavaDoc documentation to HashMapper. Add hash mapping to reference documentation. Original pull request: #194.
1 parent 359c3e4 commit c1476b7

File tree

5 files changed

+235
-123
lines changed

5 files changed

+235
-123
lines changed

src/main/asciidoc/reference/redis.adoc

Lines changed: 125 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,28 @@ http://github.com/xetorthio/jedis[Jedis] is one of the connectors supported by t
5050
[source,xml]
5151
----
5252
<?xml version="1.0" encoding="UTF-8"?>
53-
<beans xmlns="http://www.springframework.org/schema/beans"
54-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
53+
<beans xmlns="http://www.springframework.org/schema/beans"
54+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5555
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
56-
56+
5757
<!-- Jedis ConnectionFactory -->
5858
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"/>
59-
59+
6060
</beans>
6161
----
6262

6363
For production use however, one might want to tweak the settings such as the host or password:
6464

6565
[source,xml]
6666
----
67-
<?xml version="1.0" encoding="UTF-8"?>
68-
<beans xmlns="http://www.springframework.org/schema/beans"
69-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
70-
xmlns:p="http://www.springframework.org/schema/p"
67+
<?xml version="1.0" encoding="UTF-8"?>
68+
<beans xmlns="http://www.springframework.org/schema/beans"
69+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
70+
xmlns:p="http://www.springframework.org/schema/p"
7171
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
72-
72+
7373
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="server" p:port="6379" />
74-
74+
7575
</beans>
7676
----
7777

@@ -85,13 +85,13 @@ A typical JRedis configuration can looks like this:
8585
[source,xml]
8686
----
8787
<?xml version="1.0" encoding="UTF-8"?>
88-
<beans xmlns="http://www.springframework.org/schema/beans"
88+
<beans xmlns="http://www.springframework.org/schema/beans"
8989
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
90-
xmlns:p="http://www.springframework.org/schema/p"
90+
xmlns:p="http://www.springframework.org/schema/p"
9191
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
92-
92+
9393
<bean id="jredisConnectionFactory" class="org.springframework.data.redis.connection.jredis.JredisConnectionFactory" p:host-name="server" p:port="6379"/>
94-
94+
9595
</beans>
9696
----
9797

@@ -101,9 +101,9 @@ The configuration is quite similar to Jedis, with one notable exception. By defa
101101
----
102102
<?xml version="1.0" encoding="UTF-8"?>
103103
<beans xmlns="http://www.springframework.org/schema/beans"
104-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
104+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
105105
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
106-
106+
107107
<bean id="jredisConnectionFactory" class="org.springframework.data.redis.connection.jredis.JredisConnectionFactory">
108108
<constructor-arg>
109109
<bean class="org.springframework.data.redis.connection.jredis.DefaultJredisPool">
@@ -112,7 +112,7 @@ The configuration is quite similar to Jedis, with one notable exception. By defa
112112
</bean>
113113
</constructor-arg>
114114
</bean>
115-
115+
116116
</beans>
117117
----
118118

@@ -125,14 +125,14 @@ By now, its configuration is probably easy to guess:
125125

126126
[source,xml]
127127
----
128-
<?xml version="1.0" encoding="UTF-8"?>
129-
<beans xmlns="http://www.springframework.org/schema/beans"
128+
<?xml version="1.0" encoding="UTF-8"?>
129+
<beans xmlns="http://www.springframework.org/schema/beans"
130130
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
131131
xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="
132132
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
133-
133+
134134
<bean id="srpConnectionFactory" class="org.springframework.data.redis.connection.srp.SrpConnectionFactory" p:host-name="server" p:port="6379"/>
135-
135+
136136
</beans>
137137
----
138138

@@ -148,13 +148,13 @@ Its configuration is probably easy to guess:
148148
[source,xml]
149149
----
150150
<?xml version="1.0" encoding="UTF-8"?>
151-
<beans xmlns="http://www.springframework.org/schema/beans"
152-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
153-
xmlns:p="http://www.springframework.org/schema/p"
151+
<beans xmlns="http://www.springframework.org/schema/beans"
152+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
153+
xmlns:p="http://www.springframework.org/schema/p"
154154
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
155-
155+
156156
<bean id="lettuceConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory" p:host-name="server" p:port="6379"/>
157-
157+
158158
</beans>
159159
----
160160

@@ -172,12 +172,12 @@ NOTE: Please note that currently only http://github.com/xetorthio/jedis[Jedis] a
172172
/**
173173
* jedis
174174
*/
175-
@Bean
175+
@Bean
176176
public RedisConnectionFactory jedisConnectionFactory() {
177177
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration() .master("mymaster")
178178
.sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380);
179179
return new JedisConnectionFactory(sentinelConfig);
180-
}
180+
}
181181
182182
/**
183183
* lettuce
@@ -262,33 +262,33 @@ For cases where a certain template *view* is needed, declare the view as a depen
262262
[source,xml]
263263
----
264264
<?xml version="1.0" encoding="UTF-8"?>
265-
<beans xmlns="http://www.springframework.org/schema/beans"
266-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
267-
xmlns:p="http://www.springframework.org/schema/p"
265+
<beans xmlns="http://www.springframework.org/schema/beans"
266+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
267+
xmlns:p="http://www.springframework.org/schema/p"
268268
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
269-
269+
270270
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/>
271271
<!-- redis template definition -->
272272
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
273-
...
274-
273+
...
274+
275275
</beans>
276276
----
277277

278278
[source,java]
279279
----
280-
public class Example {
281-
282-
// inject the actual template
283-
@Autowired
284-
private RedisTemplate<String, String> template;
280+
public class Example {
281+
282+
// inject the actual template
283+
@Autowired
284+
private RedisTemplate<String, String> template;
285285
286286
// inject the template as ListOperations
287-
@Resource(name="redisTemplate")
287+
@Resource(name="redisTemplate")
288288
private ListOperations<String, String> listOps;
289289
290290
public void addLink(String userId, URL url) {
291-
listOps.leftPush(userId, url.toExternalForm());
291+
listOps.leftPush(userId, url.toExternalForm());
292292
}
293293
}
294294
----
@@ -301,27 +301,27 @@ Since it's quite common for the keys and values stored in Redis to be `java.lang
301301
[source,xml]
302302
----
303303
<?xml version="1.0" encoding="UTF-8"?>
304-
<beans xmlns="http://www.springframework.org/schema/beans"
305-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
306-
xmlns:p="http://www.springframework.org/schema/p"
304+
<beans xmlns="http://www.springframework.org/schema/beans"
305+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
306+
xmlns:p="http://www.springframework.org/schema/p"
307307
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
308-
308+
309309
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/>
310-
310+
311311
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
312-
...
312+
...
313313
</beans>
314314
----
315315

316316
[source,java]
317317
----
318-
public class Example {
319-
318+
public class Example {
319+
320320
@Autowired
321-
private StringRedisTemplate redisTemplate;
322-
321+
private StringRedisTemplate redisTemplate;
322+
323323
public void addLink(String userId, URL url) {
324-
redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
324+
redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
325325
}
326326
}
327327
----
@@ -330,12 +330,12 @@ As with the other Spring templates, `RedisTemplate` and `StringRedisTemplate` al
330330

331331
[source,java]
332332
----
333-
public void useCallback() {
333+
public void useCallback() {
334334
335-
redisTemplate.execute(new RedisCallback<Object>() {
336-
public Object doInRedis(RedisConnection connection) throws DataAccessException {
335+
redisTemplate.execute(new RedisCallback<Object>() {
336+
public Object doInRedis(RedisConnection connection) throws DataAccessException {
337337
Long size = connection.dbSize();
338-
// Can cast to StringRedisConnection if using a StringRedisTemplate
338+
// Can cast to StringRedisConnection if using a StringRedisTemplate
339339
((StringRedisConnection)connection).set("key", "value");
340340
}
341341
});
@@ -345,7 +345,57 @@ public void useCallback() {
345345
[[redis:serializer]]
346346
== Serializers
347347

348-
From the framework perspective, the data stored in Redis is just bytes. While Redis itself supports various types, for the most part these refer to the way the data is stored rather than what it represents. It is up to the user to decide whether the information gets translated into Strings or any other objects. The conversion between the user (custom) types and raw data (and vice-versa) is handled in Spring Data Redis through the `RedisSerializer` interface (package `org.springframework.data.redis.serializer`) which as the name implies, takes care of the serialization process. Multiple implementations are available out of the box, two of which have been already mentioned before in this documentation: the `StringRedisSerializer` and the `JdkSerializationRedisSerializer`. However one can use `OxmSerializer` for Object/XML mapping through Spring 3 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/oxm.html[OXM] support or either `JacksonJsonRedisSerializer`, `Jackson2JsonRedisSerializer` or `GenericJackson2JsonRedisSerializer for storing data in http://en.wikipedia.org/wiki/JSON[JSON] format. Do note that the storage format is not limited only to values - it can be used for keys, values or hashes without any restrictions.
348+
From the framework perspective, the data stored in Redis is just bytes. While Redis itself supports various types, for the most part these refer to the way the data is stored rather than what it represents. It is up to the user to decide whether the information gets translated into Strings or any other objects. The conversion between the user (custom) types and raw data (and vice-versa) is handled in Spring Data Redis through the `RedisSerializer` interface (package `org.springframework.data.redis.serializer`) which as the name implies, takes care of the serialization process. Multiple implementations are available out of the box, two of which have been already mentioned before in this documentation: the `StringRedisSerializer` and the `JdkSerializationRedisSerializer`. However one can use `OxmSerializer` for Object/XML mapping through Spring 3 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/oxm.html[OXM] support or either `JacksonJsonRedisSerializer`, `Jackson2JsonRedisSerializer` or `GenericJackson2JsonRedisSerializer` for storing data in http://en.wikipedia.org/wiki/JSON[JSON] format. Do note that the storage format is not limited only to values - it can be used for keys, values or hashes without any restrictions.[[redis:serializer]]
349+
350+
== Hash mapping
351+
352+
Data can be stored using various data structures within Redis. You already learned about `Jackson2JsonRedisSerializer` which can convert objects
353+
in http://en.wikipedia.org/wiki/JSON[JSON] format. JSON can be ideally stored as value using plain keys. A more sophisticated mapping of structured objects
354+
can be achieved using Redis Hashes. Spring Data Redis offers various strategies for mapping data to hashes depending on the use case.
355+
356+
1. Direct mapping using `HashOperations` and a <<redis:serializer,serializer>>
357+
2. Using <<redis.repositories>>
358+
3. Using `HashMapper` and `HashOperations`
359+
360+
=== Hash mappers
361+
362+
Hash mappers are converters to map objects to a `Map<K, V>` and back. `HashMapper` is intended for using with Redis Hashes.
363+
364+
Multiple implementations are available out of the box:
365+
366+
1. `BeanUtilsHashMapper` using Spring's http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/BeanUtils.html[BeanUtils]
367+
2. `ObjectHashMapper` using <<redis.repositories.mapping>>
368+
369+
[source,java]
370+
----
371+
public class Person {
372+
String firstname;
373+
String lastname;
374+
375+
// …
376+
}
377+
378+
public class HashMapping {
379+
380+
@Autowired
381+
HashOperations<String, byte[], byte[]> hashOperations;
382+
383+
HashMapper<Object, byte[], byte[]> mapper = new ObjectHashMapper();
384+
385+
public void writeHash(String key, Person person) {
386+
387+
Map<byte[], byte[]> mappedHash = mapper.toHash(person);
388+
hashOperations.putAll(key, mappedHash);
389+
}
390+
391+
public Person loadHash(String key) {
392+
393+
Map<byte[], byte[]> loadedHash = hashOperations.entries("key");
394+
return (Person) mapper.fromHash(loadedHash);
395+
}
396+
}
397+
----
398+
349399

350400
:leveloffset: 2
351401
include::{referenceDir}/redis-messaging.adoc[]
@@ -371,27 +421,27 @@ _FIFO (First-In-First-Out)_, _LIFO (Last-In-First-Out)_ or _capped collection_ w
371421

372422
[source,xml]
373423
----
374-
<?xml version="1.0" encoding="UTF-8"?>
375-
<beans xmlns="http://www.springframework.org/schema/beans"
424+
<?xml version="1.0" encoding="UTF-8"?>
425+
<beans xmlns="http://www.springframework.org/schema/beans"
376426
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
377427
xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="
378-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
428+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
379429
380-
<bean id="queue" class="org.springframework.data.redis.support.collections.DefaultRedisList">
381-
<constructor-arg ref="redisTemplate"/>
382-
<constructor-arg value="queue-key"/>
430+
<bean id="queue" class="org.springframework.data.redis.support.collections.DefaultRedisList">
431+
<constructor-arg ref="redisTemplate"/>
432+
<constructor-arg value="queue-key"/>
383433
</bean>
384-
434+
385435
</beans>
386436
----
387437

388438
[source,java]
389439
----
390-
public class AnotherExample {
391-
440+
public class AnotherExample {
441+
392442
// injected
393443
private Deque<String> queue;
394-
444+
395445
public void addTag(String tag) {
396446
queue.push(tag);
397447
}
@@ -408,18 +458,18 @@ Spring Redis provides an implementation for Spring http://docs.spring.io/spring/
408458
[source,xml]
409459
----
410460
<beans xmlns="http://www.springframework.org/schema/beans"
411-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
461+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
412462
xmlns:cache="http://www.springframework.org/schema/cache"
413-
xmlns:c="http://www.springframework.org/schema/c"
463+
xmlns:c="http://www.springframework.org/schema/c"
414464
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
415-
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
465+
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
416466
417-
<!-- turn on declarative caching -->
418-
<cache:annotation-driven />
467+
<!-- turn on declarative caching -->
468+
<cache:annotation-driven />
419469
420-
<!-- declare Redis Cache Manager -->
421-
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:template-ref="redisTemplate"/>
422-
</beans>
470+
<!-- declare Redis Cache Manager -->
471+
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:template-ref="redisTemplate"/>
472+
</beans>
423473
----
424474

425475
NOTE: By default `RedisCacheManager` will lazily initialize `RedisCache` whenever a `Cache` is requested. This can be changed by predefining a `Set` of cache names.

0 commit comments

Comments
 (0)