Introduce EzyRedis

Updated at 1699804052000

1. Introduce EzyRedis

EzyRedis (Easy going to Redis Interaction) is a framework support to interact to Redis, It supports:
  1. Interacts to HMAP
  2. Pub/Sub message
  3. Serialize/Deserialize between byte array and POJO
  4. Annotation driven

2. Structure of EzyRedis

  1. Redis proxy: wraps redis client object like Jedis
  2. Map proxy: wraps hget, hset, hdel .. functions
  3. Atomic Long proxy: wraps hincrBy function
  4. Message Channel: wraps publish/subscribe functions

3. Install EzyRedis

1. To create EzyRedis we need add dependency

<dependency>
    <groupId>com.tvd12</groupId>
    <artifactId>ezydata-redis</artifactId>
    <version>1.2.8</version>
</dependency>

The latest version can be found in the Maven Central repository. 2. To use EzyRedis you need config to create repositories You can use ezyfox-boot-autoconfigure by add to your pom.xml:

<dependency>
    <groupId>com.tvd12</groupId>
    <artifactId>ezyfox-boot-autoconfigure</artifactId>
    <version>1.1.0</version>
</dependency>

Or because with some reason, you can not use ezyfox-boot-autoconfigure, you can config like this:

    import com.tvd12.ezydata.redis.EzyRedisClientPool;
    import com.tvd12.ezydata.redis.EzyRedisProxy;
    import com.tvd12.ezydata.redis.EzyRedisProxyFactory;
    import com.tvd12.ezydata.redis.loader.EzyJedisClientPoolLoader;
    import com.tvd12.ezyfox.bean.EzyBeanAutoConfig;
    import com.tvd12.ezyfox.bean.EzySingletonFactory;
    import com.tvd12.ezyfox.bean.EzySingletonFactoryAware;
    import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
    import com.tvd12.ezyfox.util.EzyPropertiesAware;
    import lombok.Setter;
    import java.util.Properties;
    import java.util.Set;
    @Setter
    @EzyConfigurationBefore
    public class EzyRedisConfiguration implements
        EzyBeanConfig,
        EzyPropertiesAware,
        EzySingletonFactoryAware {
        private Properties properties;
        private EzySingletonFactory singletonFactory;
        @Override
        public void autoConfig() {
            singletonFactory.addSingleton("redisProxy", newRedisProxy());
        }
        private EzyRedisProxy newRedisProxy() {
            return EzyRedisProxyFactory.builder()
                .properties(properties)
                .scan("your packages to scan")
                .clientPool(newClientPool())
                .build()
                .newRedisProxy();
        }
        protected EzyRedisClientPool newClientPool() {
            return new EzyJedisClientPoolLoader()
                .properties(properties)
                .load();
        }
    }

3. You can add to your configuration file like this:

    # for application.yaml
    redis:
      uri: redis://localhost:6379/
      map_naming:
        case: CAMEL
        ingored_suffix: Entity
    # for application.properties
    redis.uri=redis://localhost:6379/
    redis.map_naming.case=CAMEL
    redis.map_naming.ingored_suffix=Entity

4. Example

Let’s say we need create an http server application to manage a book store (Category, Author and Book), we need 6 apis

  • api/v1/author/add: Add an author
  • api/v1/category/add: Add a category
  • api/v1/book/add: Add a book
  • api/v1/books/{bookId}: Get a book by id
  • api/v1/books: Get a list of books
  • apiv1/books/expected-revenue:

4.1 Create data classes

To store Category, Author and Book to Redis, we need create 3 data classes

    import com.tvd12.ezyfox.data.annotation.EzyCachedKey;
    import com.tvd12.ezyfox.data.annotation.EzyCachedValue;
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    @Getter
    @Setter
    @EzyCachedValue
    @NoArgsConstructor
    @AllArgsConstructor
    public class Category {
        @EzyCachedKey
        private Long id;
        private String name;
    }
    @Getter
    @Setter
    @EzyCachedValue
    @AllArgsConstructor
    @NoArgsConstructor
    public class Author {
        @EzyCachedKey
        private long id;
        private String name;
    }
    @Getter
    @Setter
    @EzyCachedValue
    @AllArgsConstructor
    @NoArgsConstructor
    public class Book {
        @EzyCachedKey
        private Long id;
        private Long categoryId;
        private Long authorId;
        private String name;
        private BigDecimal price;
        private LocalDate releaseDate;
        private LocalDateTime releaseTime;
    }

4.2 Use Atomic Long and Map to create an author

Let's say we need need create author with increment long Id, we can implement APIs for author like this:

    import com.tvd12.ezydata.example.redis.entity.Author;
    import com.tvd12.ezydata.example.redis.request.AddAuthorRequest;
    import com.tvd12.ezydata.redis.EzyRedisAtomicLong;
    import com.tvd12.ezydata.redis.EzyRedisProxy;
    import com.tvd12.ezyhttp.server.core.annotation.Controller;
    import com.tvd12.ezyhttp.server.core.annotation.DoPost;
    import com.tvd12.ezyhttp.server.core.annotation.RequestBody;
    import java.util.Map;
    @Controller("/api/v1/author")
    public class AuthorController {
        private final EzyRedisAtomicLong idGentor;
        private final Map authorMap;
        public AuthorController(EzyRedisProxy redisProxy) {
            this.idGentor = redisProxy.getAtomicLong("author");
            this.authorMap = redisProxy.getMap("author");
        }
        @DoPost("/add")
        public Author addAuthor(@RequestBody AddAuthorRequest request) {
            Author author = new Author(
                idGentor.incrementAndGet(),
                request.getAuthorName()
            );
            authorMap.put(author.getId(), author);
            return author;
        }
    }

You can see everything's simple, you just need redisProxy.getAtomicLong("author") to get an AtomicLong and redisProxy.getMap("author") to get a map. Further, you can put a java object to the map and EzyRedis will serialize it to byte array and put the byte array to Redis for you. You you want to get an author by id, you just need use the get method with the author id:

    Author author = authorMap.get(request.getAuthorId());

Full source code available on Github

5. Message channel usage

Let's say you want to publish/consume a message in a chat system like this: {"message": "message value"}. Now you will need a class like this:

    import com.tvd12.ezyfox.message.annotation.EzyMessage;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @EzyMessage(channel = "ezydata_chat_message")
    public class ChatMessage {
        private String message;
    }

To subscribe the ezydata_chat_message you can do like this:

    EzyRedisChannel subscribeChannel = redisProxy1.getChannel("ezydata_chat_message", ChatMessage.class)
    subcribeChannel.addSubscriber(m -> System.out.println("received message: " + m));

To publish a message to the ezydata_chat_message channel, you can do like this:

    EzyRedisChannel publishChannel = redisProxy2.getChannel("ezydata_chat_message", ChatMessage.class)
    publishChannel.publish(new ChatMessage("Hello World"));

6. Conclusion

With EzyRedis you will work with Redis lot easier and more native. With query string, you will don't need care about bson, criteria and you will reduce a lot of your source code.