iku8blog - 考えない為に考える

SpringBootでRedis OM Springを使ってみた

date: 2023-01-08

Redis OM Spring は、Spring で JSON を扱うためのライブラリです。 これを使うことで、Java オブジェクトを json 形式で Redis に出し入れすることが簡単に出来ます。

Key-Value 形式で Json オブジェクトを Redis に保存することも出来ますが、シリアライズする手間やオーバーヘッドがアプリケーション側で発生するので、Json を使いたい場合は、このライブラリを使うのが良さそうです。 また、RedisDocumentRepository というインターフェースが用意されており、これ経由で直感的にオブジェクトの操作が可能になります。MyBatis や Jooq で RDB を使っているような感覚で redis 操作ができるのとても使い勝手が良いです。

2023/01/08 時点では SpringBoot3,java17 には対応していないらしく、今回は springboot2,java11 で試してみます。 ちなみに Redis のクライアントライブラリは Jedis のみにしか対応しておらず、設定に一手間必要です。

https://github.com/redis/redis-om-spring 公式サイト通りにやってもうまく動かないので、ちまちま変えてきます。

プロジェクト作成

spring initializr で作っていきます。

Dependencies は

  • lombok
  • spring web

だけで OK です。

Gradle(Groovy)で springboot2.7.7、java11 でプロジェクト生成します。

redis om spring の Dependencies を追加

build.gradle に以下追加します。

	implementation 'com.redis.om:redis-om-spring:0.6.3'

これで、redis om spring が使えるようになります。

Jedis 設定

Jedis 経由で redis を使う必要があるので、設定ファイルを記述します。localhost に redis を用意しておくので特段ホストやポートの設定はデフォルトから帰る必要はありません

JedisConfig.java

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class JedisConfig {

    @Bean
    JedisPoolConfig jedisPoolConfig() {
        return new JedisPoolConfig();
    }

    @Bean
    public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {

        RedisStandaloneConfiguration hostConfig = new RedisStandaloneConfiguration();

        JedisClientConfiguration.JedisClientConfigurationBuilder builder = JedisClientConfiguration.builder();
        JedisClientConfiguration clientConfig = builder
                .usePooling()
                .poolConfig(jedisPoolConfig)
                .build();

        return new JedisConnectionFactory(hostConfig, clientConfig);
    }
}

Redis リポジトリを DI できるようにする

@EnableRedisDocumentRepositoriesを付与します。これにより redis om spring のリポジトリが使えるようになります。 後に作成するリポジトリで書き込みや取得等を行います。

DemoApplication.java

package com.example.demo;

import com.redis.om.spring.annotations.EnableRedisDocumentRepositories;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableRedisDocumentRepositories //追加
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

保存用のクラスを作成する

今回は User クラスを作成して、ID をキーにして名前と年齢を保持することにします。

package com.example.demo;

import com.redis.om.spring.annotations.Document;
import com.redis.om.spring.annotations.Searchable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.data.annotation.Id;

@Getter
@AllArgsConstructor
@Document
public class User {
    @Id
    private String userId;
    private String name;
    private Integer age;
}

@Id をつけることで、findById の ID としてみなすことが出来ます。フィールド名が id であれば@Id をつけなくても勝手にさがしてくれますが、慣習的につけておきましょう。 今回はわかりやすく userId と命名しておきます。

リポジトリを作成

以下のインターフェースを作成します。

UserRepository.java

package com.example.demo;

import com.redis.om.spring.repository.RedisDocumentRepository;

public interface UserRepository extends RedisDocumentRepository<User, String> {

}

先に設定した@EnableRedisDocumentRepositoriesによって、実装クラスが DI されるようになります。

Redis 起動

redis を起動する必要があるのですが、デフォルトの redis だと Json が使えないので、 RedisJson を使う必要があります。

以下のコマンドで docker を使って起動することが可能です。

docker run -p 6379:6379 --name redis-redisjson redislabs/rejson:latest

RedisJson を使うと、JSON.SET 等の操作ができるようになります。 ちなみに Amazon ElastiCache では JSON サポートしているようです。

操作してみる

適当にコントローラーでも作って、データを出し入れしていきます。

SampleController.java

package com.example.demo;

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class SampleController {
    private final UserRepository userRepository;

    @GetMapping("sample")
    public void sample() {
        val user = new User("user1", "sampleuser1", 20);
        userRepository.save(user);

        userRepository.findById("user1").ifPresent(e -> {
            System.out.printf(e.toString());
        });
    }
}

コードとしてはかなり直感的だと思います。 User に値をセットして、redis om spring のリポジトリを使って save します。 そして、findById で保存した id を使ってデータを取り出しています。

http://localhost:8080/sample にアクセスすると上記の操作が行われます。

debug した内容が以下になります。

ちゃんと userId:user1 のデータである sampleuser1 と 20 という値が取得できていますね。 この他にもカウントや全件取得、削除等々ももちろん操作できますし、拡張すると全文検索やコレクション検索などもできるようになるようです。

ちなみに spring 以外だと、.net や node、python でも同様のライブラリが提供されています。

SpringBoot3 に対応されたら本格的に使おう。

springboot3 で試そうとしたら、redisJSONKeyValueTemplate が見つからないとかで実行することが出来ませんでした。気長に待ちます。

date: 2023-01-08