読者です 読者をやめる 読者になる 読者になる

SpringDataRedisを使ってみる

やってみるよ!
Springは3.1.1.RELEASE、SpringDataRedisは1.0.0.RELEASEを使用。

Webアプリの最低限の構成を作ってpom.xmlに以下を追加。

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>1.0.0.RELEASE</version>
</dependency>

これでspring-data-commons-coreとかJedisとかも依存解決されます。
以下によるとコネクタはJedis、JRedis、RJCに対応してるみたいだけど、デフォルトがJedisみたい。
http://www.springsource.org/spring-data/redis(Featuresのところ)


次はアプリから使えるようにするために最低限の設定をします。

<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:host-name="localhost" p:port="6379"/>

<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>

よくある感じの。MongoでいうところのMongoDBFactoryとMongoTemplate的な。
StringRedisTemplateはキーと値の両方がStringのときに使用、それ以外はRedisTemplteを使うってイメージだと思う。多分。きっと。深く読んでない。


これを使って早速しょっぱいアプリを作ります。
とりあえずset/get/delを試したいのでそれを処理するコントローラさんをざっくり作ります。
サービスクラス分けろとか野暮なことはいいっこなしです。

@Controller
@Scope("prototype")
public class RedisStrController {

	@Autowired
	private StringRedisTemplate stringRedisTemplate; // String用のTemplate

	@RequestMapping(value="/redisstr/get", method=RequestMethod.GET)
	public String get(@RequestParam(value="key", required=true) String key,Model model) {

		// キーを指定してredisから値を取得
		String result = stringRedisTemplate.opsForValue().get(key);

		model.addAttribute("result",result);

		return "redisstr/get_end";
	}

	@RequestMapping(value="/redisstr/set", method=RequestMethod.GET)
	public String set(@RequestParam(value="key", required=true) String key,
			@RequestParam(value="value", required=true) String value,
			Model model) {

		// キーと値を指定してredisにセット
		stringRedisTemplate.opsForValue().set(key, value);

		return "redisstr/set_end";
	}

	@RequestMapping(value="/redisstr/del", method=RequestMethod.GET)
	public String del(@RequestParam(value="key", required=true) String key,Model model) {

		// キーを指定してredisから削除
		stringRedisTemplate.delete(key);

		return "redisstr/del_end";
	}
}

色々省いてますけど、setはkeyとvalueを受け取ってredisにセット、get/delはkeyだけ受け取って処理します。
とりあえずデータを入れないと始まらないのでsetを叩いてみます。


「/redisstr/set?key=testkey&value=hoge」にアクセスしてredisを確認。

redis 127.0.0.1:6379> keys *
1) "testkey"
redis 127.0.0.1:6379> get testkey
"hoge"

いけている。get/delも正しく動くことが確認できました。


次は適当なクラスをぶちこむためにまたコントローラを作ります。

@Controller
@Scope("prototype")
public class RedisController {

	@Autowired
	private RedisTemplate<String, TestDto> redisTemplate; // String以外用のTemplate

	@RequestMapping(value="/redis/get", method=RequestMethod.GET)
	public String get(@RequestParam(value="key", required=true) String key,Model model) {

		// キーを指定してredisから値を取得
		TestDto dto = redisTemplate.opsForValue().get(key);

		model.addAttribute("dto",dto);

		return "redis/get_end";
	}

	@RequestMapping(value="/redis/set", method=RequestMethod.GET)
	public String set(
			@RequestParam(value="key", required=true) String key,
			@RequestParam(value="value", required=true) String value,
			Model model) {

		TestDto dto = new TestDto();
		dto.setKey(key);
		dto.setValue(value);
		dto.setCreateDate(new Date());

		// キーと値を指定してredisにセット
		redisTemplate.opsForValue().set(key, dto);

		return "redis/set_end";
	}

	@RequestMapping(value="/redis/del", method=RequestMethod.GET)
	public String del(
			@RequestParam(value="key", required=true) String key,
			Model model) {

		// キーを指定してredisから削除
		redisTemplate.delete(key);

		return "redis/del_end";
	}
}

うむ。
さっきと違うのは使うTemplateと値がString以外ってところです。
Templateは前述のRedisTemplateを使います。
宣言するときにキーと値の型を指定してやる必要があるので、今回はキーにString、値に自作クラスを指定してます。
自作クラスは以下のかんじ。中身は別に何でもよかった。

public class TestDto implements Serializable {

	private static final long serialVersionUID = 6013601409727347724L;

	private String key;
	private String value;
	private Date createDate;

	(アクセサ略)
}

シリアライズを忘れなければ何でも。


準備が出来たので「/redis/set?key=dtotest1&value=hogehoge」を叩いてredisを確認。

redis 127.0.0.1:6379> get dtotest1
(nil)

!?
えっ。あれ。えっ。
落ち着くんだ…『素数』を数えて落ち着くんだ…。


助けてkeysさん!

redis 127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\bdtotest1"

ああ…ああ…。
なんかキーがシリアライズされてるくさい雰囲気です…。


一応取得はできる。

redis 127.0.0.1:6379> get "\xac\xed\x00\x05t\x00\bdtotest1"
"\xac\xed\x00\x05sr\x00*com.tm8r.TestDtoSt\x9a\x9e\xe7\x96<\x0c\x02\x00\x03L\x00\ncreateDatet\x00\x10Ljava/util/Date;L\x00\x03keyt\x00\x12Ljava/lang/String;L\x00\x05valueq\x00~\x00\x02xpsr\x00\x0ejava.util.Datehj\x81\x01KYt\x19\x03\x00\x00xpw\b\x00\x00\x016^\xe9\x83\bxt\x00\bdtotest1t\x00\bhogehoge"


同じアプリ使ってやる分には問題ないんですけど、なんか後で困る気がするのでなんとかします。
調べた感じだとTemplateのKeySerializerをいじってやればよさそう。
ちょっくら設定を変更してみます。

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory" p:key-serializer-ref="stringKeySerializer"/>

<bean id ="stringKeySerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

StringRedisSerializerを定義し、RedisTemplateのkeySerializerにセットしてみました。


リトライしてredis確認…!

redis 127.0.0.1:6379> keys *
1) "dtotest1"
redis 127.0.0.1:6379> get dtotest1
"\xac\xed\x00\x05sr\x00*com.tm8r.TestDtoSt\x9a\x9e\xe7\x96<\x0c\x02\x00\x03L\x00\ncreateDatet\x00\x10Ljava/util/Date;L\x00\x03keyt\x00\x12Ljava/lang/String;L\x00\x05valueq\x00~\x00\x02xpsr\x00\x0ejava.util.Datehj\x81\x01KYt\x19\x03\x00\x00xpw\b\x00\x00\x016^\xf0LBxt\x00\bdtotest1t\x00\bhogehoge"

ヤター!デキタヨー!
次こそはなんかリストとかセットとかそのへんを。

スポンサーリンク