IK.AM

@making's tech note


Spring Data Redis(1.0.0.M1)を試す

🗃 {Programming/Java/org/springframework/data/redis}
🗓 Updated at 2010-12-18T12:06:30Z  🗓 Created at 2010-12-18T12:06:30Z   🌎 English Page

SpringのNoSQL対応プロジェクトSpring DataのRedisサポート1.0.0.M1版を先日リリースしたので試してみました。 まだMavenレポジトリには登録されていなかったので暫定処置としてここからDLして、ローカルMavenレポジトリにインストールしました。

一応、メモしておくと

$ cd spring-data-redis-1.0.0.M1\dist
$ mvn install:install-file -Dfile=spring-data-keyvalue-core-1.0.0.M1.jar -Dsources=spring-data-keyvalue-core-1.0.0.M1-sources.jar -Djavadoc=spring-data-keyvalue-core-1.0.0.M1-javadoc.jar -DgroupId=org.springframework.data -DartifactId=spring-data-keyvalue-core -Dversion=1.0.0.M1 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true
$ mvn install:install-file -Dfile=spring-data-redis-1.0.0.M1.jar -Dsources=spring-data-redis-1.0.0.M1-sources.jar -Djavadoc=spring-data-redis-1.0.0.M1-javadoc.jar -DgroupId=org.springframework.data -DartifactId=spring-data-redis -Dversion=1.0.0.M1 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true

redisインストール&起動

Cygwinでさくっと

$ wget http://code.google.com/p/redis/downloads/detail?name=redis-2.0.4.tar.gz
$ tar xzvf redis-2.0.4.tar.gz
$ cd redis-2.0.4
$ make
$ ./redis-server

pom.xml

全部必要か分からないけど、pom.xmlはこんな感じ

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>am.ik</groupId>
    <artifactId>spring-data-sample</artifactId>
    <packaging>jar</packaging>
    <version>0.1</version>
    <name>spring-data-sample</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>3.0.5.RELEASE</spring.version>
        <spring.data.version>1.0.0.M1</spring.data.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Data -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-keyvalue-core</artifactId>
            <version>${spring.data.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>${spring.data.version}</version>
        </dependency>

        <!-- JRedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>1.5.0-RC1</version>
        </dependency>

        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.5.5</version>
        </dependency>

    </dependencies>
</project>

org.springframework.core.serializer.support.SerializingConverterを使用しており、Springのバージョンは3.0.5以上じゃないと動かない模様。

applicationContext.xml

Bean定義ファイルにSpringおなじみのConnectionFactoryTemplateを定義。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

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


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

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

RedisTemplateはkeyとvalueの型をジェネリクスで指定する。keyもvalueもStringの場合はStringRedisTemplateを使う。 RedisTemplateは汎用シリアライザ/でシリアライザを使い、StringRedisTemplateString用の軽いシリアライザ/でシリアライザを使うぽい。

使用例

↓前提で

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

Operationを使った例のみ試した。他にも使い方はあるようだ。

keyもvalueもStringの場合

StringRedisTemplate stringTemplate = (StringRedisTemplate) context.getBean("stringRedisTemplate");
単純な値のset/get

org.springframework.data.keyvalue.redis.core.ValueOperationsを利用します。

stringTemplate.getValueOps().set("bar", "zzz");
stringTemplate.getValueOps().get("bar"); // -> zzz
Listのset/get

org.springframework.data.keyvalue.redis.core.ListOperationsを利用します。

stringTemplate.getListOps().leftPush("lst", "xxx");
stringTemplate.getListOps().leftPush("lst", "yyy");
stringTemplate.getListOps().leftPush("lst", "zzz");
stringTemplate.getListOps().rightPush("lst", "111");

stringTemplate.getListOps().range("lst", 0, 1); // -> [zzz, yyy]
stringTemplate.getListOps().range("lst", 0, -1); // -> [zzz, yyy, xxx, 111]

stringTemplate.getListOps().leftPop("lst"); // -> zzz
stringTemplate.getListOps().rightPop("lst"); // -> 111
stringTemplate.getListOps().range("lst", 0, -1); // -> [yyy, xxx]
Hashのset/get

org.springframework.data.keyvalue.redis.core.HashOperationsを利用します。

stringTemplate.getHashOps().set("hsh", "k1", "v1");
stringTemplate.getHashOps().set("hsh", "k2", "v2");
stringTemplate.getHashOps().set("hsh", "k2", "v2");

stringTemplate.getHashOps().get("hsh", "k1"); // v1
stringTemplate.getHashOps().keys("hsh"); // [k1, k2, k3]
stringTemplate.getHashOps().values("hsh"); // [v1, v2, v3]

java.util.Map形式で取得するインタフェースがない?

他にもSetOperationsとかある。

multiSet/Get

一部のOperationでサポートされている。

Map<String, String> vals = new HashMap<String, String>();
vals.put("k1", "v1");
vals.put("k2", "v2");
vals.put("k3", "v3");
stringTemplate.getValueOps().multiSet(vals);
stringTemplate.getValueOps().multiGet(Arrays.asList("k1","k2","k3")); // [v1, v2, v3]
CAS

一部のOperationでサポートされている。

stringTemplate.getValueOps().setIfAbsent("foo", "xxx"); // 初セットの場合true、セット済みの場合false
stringTemplate.getValueOps().getAndSet("foo", "aaa"); // xxx
stringTemplate.getValueOps().get("foo"); // aaa
カウンター
stringTemplate.getValueOps().increment("counter", 1); // 1 (Long型)
stringTemplate.getValueOps().increment("counter", 1); // 2
stringTemplate.getValueOps().get("counter"); // 1 (この場合String型)

key、valueが任意のオブジェクト

次のPersonオブジェクトを値に使用します。

Person.java
public class Person implements Serializable {

    private static final long serialVersionUID = 92633004015631981L;

    private String firstName;
    private String lastName;

    private Integer age;
    private Address address;

    public Person(String firstName, String lastName, int age, Address address) {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.address = address;
    }

    // setter/getterは略

    // Eclipseの機能(Alt+Shift+S → H)でhashCode/equalsを実装する
    @Override
    public int hashCode() {
        ....
    }

    @Override
    public boolean equals(Object obj) {
        ....
    }

    @Override
    public String toString() {
        return "Person [firstName=" + firstName + ", lastName=" + lastName
                + ", age=" + age + ", address=" + address + "]";
    }
}
Address.java
public class Address implements Serializable {

    private static final long serialVersionUID = 4924045450477798779L;

    private String street;

    private Integer number;

    public Address(String street, int number) {
        super();
        this.street = street;
        this.number = number;
    }

    // Eclipseの機能(Alt+Shift+S → H)でhashCode/equalsを実装する
    @Override
    public int hashCode() {
        ....
    }

    @Override
    public boolean equals(Object obj) {
        ....
    }

    @Override
    public String toString() {
        return "Address [street=" + street + ", number=" + number + "]";
    }
}

汎用テンプレートを使用します

RedisTemplate<String, Person> template = (RedisTemplate<String, Person>) context.getBean("redisTemplate");
単純な値のset/get
Person p1 = new Person("Johon", "Smith", 20, new Address("foo", 100));
Person p2 = new Person("Taro", "Yamada", 25, new Address("aaa", 200));

template.getValueOps().set("p1", p1);
template.getValueOps().set("p2", p2);

template.getValueOps().get("p1"); // Person [firstName=Johon, lastName=Smith, age=20, address=Address [street=foo, number=100]]
template.getValueOps().get("p2"); // Person [firstName=Taro, lastName=Yamada, age=25, address=Address [street=aaa, number=200]]

その他Stringの場合と同じ。

ちなみに自分の環境では1プロセスで9回以上操作すると固まる、、、何故だ。。。


✒️️ Edit  ⏰ History  🗑 Delete