我使用绝地武士通过spring数据访问redis。

<bean
    id="jedisPoolConfig"
    class="redis.clients.jedis.JedisPoolConfig"
    p:maxTotal="100"
    p:maxIdle="10"
    p:maxWaitMillis="5000"
/>

<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:host-name="${redis.server.host}" p:port="${redis.server.port}"
    p:password="${redis.server.password}"
    p:use-pool="${redis.server.usepool}"
    p:pool-config-ref="jedisPoolConfig"/>

<bean id="genericJackson2JsonRedisSerializer" class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>

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


<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"      p:connection-factory-ref="jedisConnectionFactory">      <property name="keySerializer" ref="stringSerializer"/>
        <property name="hashKeySerializer" ref="stringSerializer"/>
        <property name="hashValueSerializer" ref="genericJackson2JsonRedisSerializer"/>
</bean>

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

想执行BRPOPLPUSH,我在下面看不到此选项
   OPTION_1  -> getRedisTemplate().boundListOps("Key").*

   OPTION_2 -> getRedisTemplate().opsForList().rightPopAndLeftPush("sourceKey", "destinationKey")  ---> No blocking ?

取而代之的是,
   OPTION_3 -> getRedisTemplate().getConnectionFactory().getConnection().bRPopLPush(timeout, srcKey, dstKey)

问:这是唯一的选择吗?为什么在以上两个api中不可用?
回答_0:no,每当在left/rightPop(timeout, unit)中用boundListOps提到时间单位时,opsForList就是阻塞呼叫。时间单位为0秒,用于永久阻塞。
问题1:为什么会有这么多的变体?或者何时使用boundListOpsopsForListgetConnection
partial_answer_1:如果要对单个键执行多个操作,则boundListOps,因为它绑定到该单个键,无需在重复操作中提及,在opsForList中,每个操作键都必须提及。
来自BoundListOps的文档:
返回对绑定到给定
关键。
请注意,boundListOps仍然通过将注册密钥传递给它来固有地使用opsForList。
好的,我什么时候应该直接使用getConnectionFactory().getConnection()
问题二:如果我使用getConnectionFactory().getConnection(),是否需要在finally(){}下关闭此连接?(因为这是目前支持blocking RPopLPush的版本)。
从代码boundListOps本身就是使用opsforlist的,它的所有操作都是通过下面的finally like和release连接来执行的,因此需要这样做。
RedisTemplate.java
 public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
RedisConnectionFactory factory = getConnectionFactory();
        RedisConnection conn = null;
        try {
            conn = RedisConnectionUtils.getConnection(factory);
            ...
            ...
        // TODO: any other connection processing?
        return postProcessResult(result, connToUse, existingConnection);
        } finally {
            RedisConnectionUtils.releaseConnection(conn, factory);
        }

问题三:为什么getRedisTemplate().boundListOps("key").rightPush(new HashMap());接受Map而不是像String/Object这样的值,尽管"key"已经提到了…?
答:这是我的问题,我已经声明过了。
public RedisTemplate<String, Map<String, Object>> getRedisTemplate() {
        return redisTemplate;
}

当从redistemplate获取引用v的defaultboundlistooperations时,传递的redistemplate对象与此相同。
public BoundListOperations<K, V> boundListOps(K key) {
    return new DefaultBoundListOperations<K, V>(key, this);
}

class DefaultBoundListOperations<K, V> extends DefaultBoundKeyOperations<K> implements BoundListOperations<K, V> {

    public DefaultBoundListOperations(K key, RedisOperations<K, V> operations) {
        super(key, operations); //RedisOperations<K, V> is converted to BoundListOperations<K, V> here
        this.ops = operations.opsForList();
    }
}

问题四:为什么getConnection().bRPopLPush接受srcKey, dstKey而不是byte[]
对不起,很多问题都是因为我在Spring数据或教程中找不到合适的Java文档来解释用法。

最佳答案

关于问题4:首先,需要注意的是redis键和值can be any binary。Spring数据模板将此抽象,让开发人员处理Java对象而不是字节数组。请参阅spring-data reference中的以下引用:
…模板为redis交互提供了一个高级抽象。虽然redisconnection提供了接受和返回二进制值(字节数组)的低级方法,但模板负责序列化和连接管理,使用户不必处理这些细节。
当使用RedisConnection时,spring似乎不知道您的键或值是什么类型,它也不努力将对象(例如String)转换为redis所理解的二进制文件,因此,您需要将原始二进制文件传递给redis。

关于redis - Spring Data支持Redis BRPOPLPUSH,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45530914/

10-11 06:48