一、Lettuceについて
Redisサーバーについては、以前のブログ記事で既に触れていますので、ここでは詳細を割愛します。LettuceとJedisは両方ともRedisサーバーに接続するクライアントプログラムですが、実装方法が異なります。JedisはRedisサーバーに直接接続しますが、マルチスレッド環境ではスレッドセーフではないため、接続プールを使用する必要があります。各Jedisインスタンスはスレッド間の同時アクセスに対応し、スレッドセーフであり、マルチスレッド環境での同時アクセスを満たします。また、スケーラブルな設計になっており、必要に応じて接続インスタンスを増やすことも可能です。
二、Maven依存関係
従来の手順に従い、まず依存関係をインポートし、次にプロパティを設定し、最後にインスタンスを作成します。Spring Bootを使用する場合、基本的な手順は似ています。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
三、プロパティ設定
ここではLettuceを使用します。Jedisを使用する場合は、以下の設定で"lettuce"を"jedis"に変更してください。
# Redis接続設定
spring.redis.host=127.0.0.1
spring.redis.password=
spring.redis.port=6379
spring.redis.timeout=1000
spring.redis.database=0
# Lettuce接続プール設定
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-active=8
四、実装例
以前のデモプロジェクトをベースに修正します。デフォルトのテンプレートはStringRedisTemplate<String,String>のみをサポートし、文字列のみを保存できます。この場合、カスタムテンプレートを定義する必要があります。カスタムテンプレートを定義した後でも文字列を保存したい場合は、RedisTemplateを使用できます。両者は競合しません。RedisCacheAutoConfigurationではカスタムRedisTemplateが定義されています。
package com.example.config;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisCacheConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setConnectionFactory(connectionFactory);
return template;
}
}
Userクラスにコンストラクタを追加します。
package com.example.model;
import java.io.Serializable;
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private int age;
private GenderType gender;
public UserInfo(String id, String name, int age, GenderType gender) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
public UserInfo() {
super();
}
@Override
public String toString() {
return "UserInfo [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
// Getter and Setter methods
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public GenderType getGender() {
return gender;
}
public void setGender(GenderType gender) {
this.gender = gender;
}
}
enum GenderType {
MAN, WOMAN
}
View Code以前のデモプロジェクトのUserControllerを修正し、StringRedisTemplateとRedisTemplateを注入してテストします。主な追加コードは39-46行目にあります。
package com.example.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.model.UserInfo;
import com.example.model.GenderType;
import com.example.mapper.ReadUserMapper;
import com.example.mapper.WriteUserMapper;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private WriteUserMapper writeUserMapper;
@Autowired
private ReadUserMapper readUserMapper;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@RequestMapping(value = "/alluser.do", method = RequestMethod.GET)
public String getAllUsers(Model model) {
List<UserInfo> users = readUserMapper.getAllUsers();
model.addAttribute("users", users);
// String型のデータをRedisに保存
stringRedisTemplate.opsForValue().set("testKey", "sampleValue");
String retrievedValue = stringRedisTemplate.opsForValue().get("testKey");
model.addAttribute("redisValue", retrievedValue);
// UserInfoオブジェクトをRedisに保存
String userKey = "user1234567890";
redisTemplate.opsForValue().set(userKey, new UserInfo(userKey, "SampleUser", 25, GenderType.MAN));
// UserInfoオブジェクトをRedisから取得
UserInfo retrievedUser = (UserInfo) redisTemplate.opsForValue().get(userKey);
model.addAttribute("userInfo", retrievedUser);
return "userList";
}
@RequestMapping(value = "/insert.do", method = RequestMethod.GET)
public String addUser(Model model) {
UserInfo newUser = new UserInfo();
newUser.setName("NewUser");
newUser.setAge(30);
writeUserMapper.insert(newUser);
List<UserInfo> users = writeUserMapper.getAllUsers();
model.addAttribute("users", users);
return "userList";
}
}
View CodeURL http://localhost:8080/user/alluser.do を開くと、Redisから取得したString型のキーとUserInfoオブジェクトが確認できます。
五、エラー処理
URLを開いた際にRedis接続タイムアウトのエラー「io.lettuce.core.RedisCommandTimeoutException: Command timed out」が発生しました。最初はタイムアウト値が小さすぎると考え、10000に設定してみましたが、依然としてエラーが発生しました。その後、以前のRedisサーバーの起動方法を確認し、redis.windows.confを使用してredis-server.exe redis.windows.confで起動したところ、問題が解決しました。以前ダブルクリックで起動していたことに問題があったようです。
ここではRedisの基本的な使用例のみを紹介します。実際のプロジェクトでは、クラスタ構成やキャッシュとの連携など、より複雑なシナリオが必要になる場合があります。これらについては後ほど追記していきます。