Redis et les HashMaps

Je viens de visionner le TIA (tool in action) de Nicolas Martignole lors de Devoxx FR 2014 sur Redis : Redis, une base Not Only NoSQL. Je l’avais loupĂ©, je passais juste aprĂšs et du coup, “lĂ©gĂšrement tendu” je me prĂ©parais “psychologiquement” ;). Je vous engage vivement Ă  le visionner, c’est une trĂšs bonne prĂ©sentation de Redis, qui en plus “sent” le vĂ©cu, puis Nicolas nous parle de son expĂ©rience rĂ©elle avec Redis.

Et du coup, ça m’a donnĂ© une idĂ©e de post pour mon Blog. Le sujet et court, mais pourra en intĂ©resser certains.

C’est probablement du Ă  l’influence de Backbone (oui oui, le framework javascript), mais souvent je reprĂ©sente mes modĂšles avec une propriĂ©tĂ© fields qui est une hashmap, gĂ©nĂ©ralement comme ceci:

public class Human {
  public HashMap<String, Object> fields = new HashMap<>();
  public Object get(String fieldName) { return this.fields.get(fieldName); }
  public void set(String fieldName, Object value) { this.fields.put(fieldName, value); }
}

Alors, on aime ou pas, mais je trouve ça pratique.

Pré-requis: avoir visionné le TIA de Nicolas.

HMSET

Il se trouve que la commande HMSET de Redis permet d’enregistrer des hashs (associĂ©s Ă  une clĂ©): http://redis.io/commands/hmset et que le driver Java Jedis (https://github.com/xetorthio/jedis) possĂšde la mĂ©thode “helper” hmset(key, map) qui permet de sauvegarder des hashmaps de ce type HashMap<String, String>. (1)

Un petit exemple ici sur le repo Jedis : https://github.com/xetorthio/jedis/blob/master/src/test/java/redis/clients/jedis/tests/commands/HashesCommandsTest.java# L81

(1): il n’y a que des types String avec Redis, donc oubliez le type Object.

Application en Java

Donc en java, si j’avais des hashmaps qui reprĂ©senteraient des humains, j’aurais le code suivant:

Connexion Ă  Redis et dĂ©finition des “humains”

Jedis jedis = new Jedis("localhost", 6379);

HashMap<String, String> bob = new HashMap<String, String>() {{
  put("firstName", "Bob");
  put("lastName", "Morane");
}};

HashMap<String, String> john = new HashMap<String, String>() {{
  put("firstName", "John");
  put("lastName", "Doe");
}};

HashMap<String, String> jane = new HashMap<String, String>() {{
  put("firstName", "Jane");
  put("lastName", "Doe");
}};

Sauvegarde des “humains”

/* === save all humans to the redis server === */

jedis.hmset("bob:male", bob);
jedis.hmset("john:male", john);
jedis.hmset("jane:female", jane);

Retrouver un “humain”

On utilise la mĂ©thode hgetAllen lui passant la clĂ© de “l’humain” recherchĂ©

/* === get Jane === */

System.out.println(jedis.hgetAll("jane:female"));

En sortie, nous aurons ceci:

{lastName=Doe, firstName=Jane}

Lister toutes les clés

/* === get All Humans keys === */

jedis.keys("*").forEach((key)->System.out.println(key));

En sortie, nous aurons ceci:

bob:male
john:male
jane:female

Lister toutes les “humains”

Pour cela nous passerons par la liste des clés:

/* === get All Humans === */

jedis.keys("*").forEach((key)->System.out.println(jedis.hgetAll(key)));

En sortie, nous aurons ceci:

{firstName=Bob, lastName=Morane}
{firstName=John, lastName=Doe}
{lastName=Doe, firstName=Jane}

Ne lister que les garçons

/* === get only males === */
jedis.keys("*:male").forEach((key)->System.out.println(jedis.hgetAll(key)));

En sortie, nous aurons ceci:

{firstName=Bob, lastName=Morane}
{firstName=John, lastName=Doe}

Remarquez la façon d’utiliser la mĂ©thode keys : on utilise comme paramĂštre *:male qui signifie: “je veux toutes les clĂ©s qui se termine par :male“.

Ce qui signifie que la clĂ© est porteuse d’informations et qu’il est important de bien rĂ©flĂ©chir Ă  la maniĂšre de la construire.

Vous trouverez le code source ici: https://github.com/java-experiments/try-redis-with-jedis

En Golo pour la route

Juste le listing Golo, qui se passe d’explication (la logique reste la mĂȘme)

(Cela faisait en partie partie de mon TIA Golo, de la sucrette syntaxique pour vos applications Java)

let jedis = Jedis("localhost", 6379)

let bob = map[["firstName", "Bob"], ["lastName", "Morane"]]
let john = map[["firstName", "John"], ["lastName", "Doe"]]
let jane = map[["firstName", "Jane"], ["lastName", "Doe"]]

#  === save all humans to the redis server ===

jedis: hmset("bob:male", bob)
jedis: hmset("john:male", john)
jedis: hmset("jane:female", jane)

#  === get Jane ===

println(jedis: hgetAll("jane:female"))

#  === get All Humans keys ===

jedis: keys("*"): each(|key| -> println(key))

#  === get All Humans ===

jedis: keys("*"): each(|key| -> println(jedis: hgetAll(key)))

#  === get only males ===

jedis: keys("*:male"): each(|key| -> println(jedis: hgetAll(key)))

Vous trouverez le code source ici: https://github.com/golo-sandbox/try-redis-with-golo

Demain, je vous parle encore de Redis mais avec du Node.js.

blog comments powered by Disqus

Related posts