C贸mo funciona Spring Data con Redis

Redis (Remote Dictionary Server) es merecidamente considerado un anciano en el mundo de las soluciones NoSql. Esta publicaci贸n trata sobre c贸mo funciona Spring Data con 茅l. La idea de escribir esta publicaci贸n surgi贸 porque Redis no es como una base de datos familiar, admite tipos de datos que no son convenientes de usar para almacenar objetos (el cach茅 no cuenta) y para buscar ciertos campos. Aqu铆, con ejemplos, intentar茅 describir c贸mo Spring Data trabaja con 茅l a trav茅s del conocido CrudRepository y QueryDSL. Este no es un ejemplo de HowTo, de los cuales hay muchos. Quien est茅 interesado en el interior ir m谩s all谩.

Los ejemplos se basar谩n en un proyecto sencillo . Redis se eleva en un contenedor de ventana acoplable, una aplicaci贸n de arranque de primavera que tambi茅n se comunica con 茅l en el contenedor. La aplicaci贸n contiene un modelo, repositorio, servicio y controlador simples. Puede tocar todo esto a trav茅s de swagger en localhost: 8080.

Adem谩s de los comandos que el servicio ejecuta en la base de datos, tambi茅n proporcionar茅 un peque帽o pseudoc贸digo que describe m谩s claramente lo que est谩 sucediendo.



Trabajaremos con la entidad Student:

@Data
@AllArgsConstructor
@NoArgsConstructor
@RedisHash("Student")
public class Student {
    @Id
    private String id;
    private String name;
    private int age;
}

Aqu铆, es necesario aclarar que la anotaci贸n @RedisHash("Student")dice bajo qu茅 clave se agregar谩n todas las entidades.

Intentemos mantener al primer alumno:

curl -X POST "http://localhost:8080/save" -H  "accept: */*" -H  "Content-Type: application/json" -d "{\"id\":\"1\",\"name\":\"Stephen\",\"age\":12}"

Se ejecutaron 3 comandos:

"DEL" "Student:1"
"HMSET" "Student:1" "_class" "com.odis.redisserviceweb.model.Student" "id" "1" "name" "Stephen" "age" "12"
"SADD" "Student" "1"

, - "DEL" "Student:1", "Student:1". @RedisHash + @Id.

"HMSET" "Student:1" "_class" "com.odis.redisserviceweb.model.Student" "id" "1" "name" "Stephen" "age" "12". "Student:1". -

Map "Student:1";
"Student:1".put("_class", "com.odis.redisserviceweb.model.Student");
"Student:1".put("id", "1");
"Student:1".put("name", "Stephen");
"Student:1".put("age", "12");

- "SADD" "Student" "1" - "Student" "1".

? Redis. - "Student:1", - "Student".

keys * - ( ) :

127.0.0.1:6379> keys *
1) "Student"
2) "Student:1"

, :

127.0.0.1:6379> type "Student"
set
127.0.0.1:6379> type "Student:1"
hash

- ? .

@Id :

curl -X GET "http://localhost:8080/get/1" -H  "accept: */*"

"Student:1" , :

"HGETALL" "Student:1"
1) "_class"
2) "com.odis.redisserviceweb.model.Student"
3) "id"
4) "1"
5) "name"
6) "Stephen"
7) "age"
8) "12"

, , :

curl -X POST "http://localhost:8080/save" -H  "accept: */*" -H  "Content-Type: application/json" -d "{\"id\":\"2\",\"name\":\"Macaulay\",\"age\":40}"
curl -X GET "http://localhost:8080/get" -H  "accept: */*"

3 :

"SMEMBERS" "Student"
1) "1"
2) "2"

"HGETALL" "Student:1"
1) "_class"
2) "com.odis.redisserviceweb.model.Student"
3) "id"
4) "1"
5) "name"
6) "Stephen"
7) "age"
8) "12"
127.0.0.1

"HGETALL" "Student:2"
1) "_class"
2) "com.odis.redisserviceweb.model.Student"
3) "id"
4) "2"
5) "name"
6) "Macaulay"
7) "age"
8) "40"

. - "Student" - , "Student:@Id". , O (N) N - .

:

curl -X DELETE "http://localhost:8080/delete/1" -H  "accept: */*"

:

"HGETALL" "Student:1"
1) "_class"
2) "com.odis.redisserviceweb.model.Student"
3) "id"
4) "1"
5) "name"
6) "Stephen"
7) "age"
8) "12"

"DEL" "Student:1"
(integer) 1

"SREM" "Student" "1"
(integer) 1

"SMEMBERS" "Student:1:idx"
(empty array)

"DEL" "Student:1:idx"
(integer) 0

, Id . "Student" "1".

Student:1:idx. . , . :

List<Student> findAllByName(String name);

:

curl -X POST "http://localhost:8080/save" -H  "accept: */*" -H  "Content-Type: application/json" -d "{\"id\":\"1\",\"name\":\"Stephen\",\"age\":12}"
curl -X GET "http://localhost:8080/get/filter/Stephen" -H  "accept: */*"

, Redis :

"SINTER" "Student:name:Stephen"
(empty array)

"SINTER" - , , - "Student:name:Stephen" .



, , @Id, @Indexed Spring Data , . . Redis . name :

@Data
@AllArgsConstructor
@NoArgsConstructor
@RedisHash("Student")
public class Student {
    @Id
    private String id;
    @Indexed
    private String name;
    private int age;
}

:

curl -X POST "http://localhost:8080/save" -H  "accept: */*" -H  "Content-Type: application/json" -d "{\"id\":\"1\",\"name\":\"Stephen\",\"age\":12}"

:

"DEL" "Student:1"
"HMSET" "Student:1" "_class" "com.odis.redisserviceweb.model.Student" "id" "1" "name" "Stephen" "age" "12"
"SADD" "Student" "1"
"SADD" "Student:name:Stephen" "1"
"SADD" "Student:1:idx" "Student:name:Stephen"

, : "Student:name:Stephen" , , @Indexed . Id . Id Stephen Id . , . - :

Map "Student:1";
"Student:1".put("_class", "com.odis.redisserviceweb.model.Student");
"Student:1".put("id", "1");
"Student:1".put("name", "Stephen");
"Student:1".put("age", "12");

Set "Student";
"Student".add("1");

Set "Student:name:Stephen";
"Student:name:Stephen".add("1");

Set "Student:1:idx";
"Student:1:idx".add("Student:name:Stephen");

, , Redis :

"SINTER" "Student:name:Stephen"
"HGETALL" "Student:1"

Id , . .

SINTER . id .

.

, Spring Data Redis. Spring.



La desventaja es que los campos en los que se realizar谩 la b煤squeda deben estar marcados @Indexedcon una anotaci贸n desde el principio. De lo contrario, solo se crear谩n "铆ndices" para las entidades que se conservan despu茅s de agregar esta anotaci贸n. Y s铆, entiendo que Redis no es la mejor soluci贸n para este tipo de necesidades, pero si por una determinada situaci贸n es necesario utilizarlo, SpringData podr谩 hacerlo bastante bien.




All Articles