Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

An Introduction to Redis and Its Unique Structures With Java

DZone's Guide to

An Introduction to Redis and Its Unique Structures With Java

Get an overview of Redis and its structures, see how to integrate JNoSQL with Redis, and learn about Redis model operations.

· Database Zone ·
Free Resource

MariaDB TX, proven in production and driven by the community, is a complete database solution for any and every enterprise — a modern database for modern applications.

Redis is a software project that implements data structure servers. It is open-source, networked, and in-memory, and it stores keys with optional durability. Redis is the most popular key-value database; it supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, and much more. Redis works with an in-memory dataset. However,
it can persist it by dumping the dataset to disk or this persistence can be optionally disabled. This post will cover an introduction to Redis and its structures.

Redis Structures

As mentioned in this post about a key-value database, these databases have special structures that are a considerable advantage to several scenarios. At Redis, there are the following structures.

List

Redis Lists are simply lists of strings, sorted by insertion order. It is possible to add elements to a Redis List pushing new elements on the head (on the left) or on the tail (on the right) of the list. It looks like a List in the Java world.

Sets

Redis Sets are an unordered collection of Strings. It is possible to add, remove, and test for the existence of members in O(1) (constant time regardless of the number of elements contained inside the Set). They look like a Set in the Java world.

Hashes

Redis Hashes are maps between string fields and string values, so they are the perfect data type to represent objects (i.e. a User with a number of fields like name, surname, age, and so forth). They look like a Map in the Java world.

Sorted Sets

Redis Sorted Sets are, similarly to Redis Sets, non-repeating collections of Strings. The difference is that every member of a Sorted Set is associated with a score that is used to make the sorted set ordered from the smallest to the greatest score. While members are unique, scores may be repeated. There isn't any standard to represent this skeleton in the Java SDK. 

Install Redis

To Install Redis, you can use either manual installation or download the Docker image.

docker run --name redis-instance -p 6379:6379 -d redis

JNoSQL Integration

As with any JNoSQL integration, you will need CDI and Java 8 or higher to run this sample. The first step is to set the dependencies. Once all information inside the Redis is text, if the type is different than the String, the framework will convert it to JSON using JSON-B, the standard API to serialize/deserialize JSON. In this example, it set the reference implementation of this API.

       <dependency>
            <groupId>javax.json</groupId>
            <artifactId>javax.json-api</artifactId>
            <version>${javax.json.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.json.bind</groupId>
            <artifactId>javax.json.bind-api</artifactId>
            <version>${javax.json.bind}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse</groupId>
            <artifactId>yasson</artifactId>
            <version>${json.b.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>${javax.json.version}</version>
        </dependency>

        <dependency>
            <groupId>org.jnosql.artemis</groupId>
            <artifactId>artemis-key-value</artifactId>
            <version>${jnosql.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jnosql.diana</groupId>
            <artifactId>redis-driver</artifactId>
            <version>${jnosql.version}</version>
        </dependency>

The Model Operations

To define a model, a Java developer can integrate JSON-B with JNoSQL. Beyond the Entity and Id annotations, this application has JSON-B annotations that show how to deserialize the Entity from JSON against the Java constructor.

@Entity
public class God implements Serializable {

    @Id
    private String id;

    private String power;

    private Set<String> duties;

    @JsonbCreator
    public God(@JsonbProperty("id") String id,
        @JsonbProperty("power")String power,
        @JsonbProperty("duties")Set<String> duties) {

        this.id = requireNonNull(id, "id is required");
        this.power = requireNonNull(power, "power is required");
        this.duties = requireNonNull(duty, "duties is required");
    }
}

To operate with this model, we can use either a template class or create a Repository interface.

public class Main {

    public static void main (String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
            Set<String> duties = new HashSet<>();
            duties.add("music");
            duties.add("poetry");
            duties.add("medicine");

            God apollo = God.builder()
                    .id("Apollo")
                    .power("Sun")
                    .duties(duties)
                    .build();

            KeyValueTemplate keyValueTemplate = container.select(KeyValueTemplate.class).get();

            God godSaved = keyValueTemplate.put(apollo);
            System.out.println(godSaved);

            Optional<God> godFound = keyValueTemplate.get("Apollo", God.class);
            System.out.println(godFound);
        }
    }

}
public interface GodRepository extends Repository<God, String> {

}
public class Main2 {

    public static void main (String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            Set<String> duties = new HashSet<>();
            duties.add("moon");
            duties.add("hunt");

            God artemis = God.builder()
                    .id("artemis")
                    .power("archery")
                    .duties(duties)
                    .build();


            GodRepository repository = container.select(GodRepository.class, DatabaseQualifier.ofKeyValue()).get();
            God godSaved = repository.save(artemis);
            System.out.println(godSaved);

            Optional<God> godFound = repository.findById("artemis");
            System.out.println(godFound);
        }
    }

}

Standard Structure

To make it easier for Java developers, all Redis commands (i.e. LPUSH and SADD) were wrapped with Jedis in a Java Collection, as you can see below.

public class Main3 {

    public static void main (String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            List<String> gods = container.select(new TypeLiteral<List<String>>() {}).get();
            gods.clear();
            System.out.println("Adds new gods");

            gods.add("Artemis");
            gods.add("Diana");
            gods.add("Diana");
            gods.add("Poseidon");

            gods.forEach(System.out::println);
            System.out.println("Removing an element");
            gods.remove("Diana");

            gods.forEach(System.out::println);


        }
    }

}
public class Main4 {

    public static void main (String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            Set<String> gods = container.select(new TypeLiteral<Set<String>>() {}).get();
            gods.clear();
            System.out.println("Adds new gods");

            gods.add("Artemis");
            gods.add("Diana");
            gods.add("Diana");
            gods.add("Poseidon");

            gods.forEach(System.out::println);
            System.out.println("Removing an element");
            gods.remove("Diana");

            gods.forEach(System.out::println);


        }
    }

}
public class Main5 {

    public static void main (String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            Queue<String> gods = container.select(new TypeLiteral<Queue<String>>() {}).get();
            gods.clear();
            System.out.println("Adds new gods");

            gods.add("Artemis");
            gods.add("Diana");
            gods.add("Poseidon");

            gods.forEach(System.out::println);

            System.out.println("Pool element: " + gods.poll());
            System.out.println("Pool element: " + gods.poll());
            System.out.println("Pool element: " + gods.poll());
            System.out.println("Pool element: " + gods.poll());
            System.out.println("Pool element: " + gods.poll());

            gods.forEach(System.out::println);


        }
    }

}
public class Main6 {

    public static void main(String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            Map<String, String> gods = container.select(new TypeLiteral<Map<String, String>>() {
            }).get();

            gods.clear();

            gods.put("hunt", "Artemis");
            gods.put("Sun", "Apollo");
            gods.put("Sea", "Poseidon");


            System.out.println("hunt: " + gods.get("hunt"));
            System.out.println("Sun: " + gods.get("Sun"));
            System.out.println("Sea: " + gods.get("Sea"));
            System.out.println("the keys: " + gods.keySet());

        }
    }

}

Beyond the Normalize

There is an interface that represents SortedSet and also a counter with Redis.

public class Main7 {

    public static void main (String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            SortedSet gods = container.select(SortedSet.class).get();
            gods.add("Artemis", 10);
            gods.add("Hera", 5);
            gods.add("Zeus", 2);
            gods.add("Apollo", 1);

            System.out.println("The ranking:");
            gods.getRanking().forEach(System.out::println);

            System.out.println("The reverse ranking:");
            gods.getRevRanking().forEach(System.out::println);

            System.out.println("The worse goods: " + gods.range(0, 1));
            System.out.println("The best ones: " + gods.revRange(0, 1));

        }
    }

}
public class Main8 {

    public static void main (String[] args) {
        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            Counter gods = container.select(Counter.class).get();
            System.out.println("increment: " + gods.increment());
            System.out.println("increment: " + gods.increment(2));
            System.out.println("decrement: " + gods.decrement(2));



        }
    }

}

References

MariaDB AX is an open source database for modern analytics: distributed, columnar and easy to use.

Topics:
redis ,jnosql ,database ,tutorial ,database structure

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}