redisTemplate的spring配置以及lua脚本驱动

  最近在使用spring-data-redis的redisTemplate,所以写篇使用记录吧。

  1.不用多说,使用maven引入相关依赖,因为项目已经引入其他的

  

<dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.6.2.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>spring-context</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-aop</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-context-support</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-tx</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-core</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

2.spring配置文件

<bean  class="redis.clients.jedis.JedisPoolConfig">
          <property name="maxIdle" value="${redis.maxIdle}" />
          <property name="maxActive" value="${redis.maxActive}" />
          <property name="maxWait" value="${redis.maxWait}" />
          <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>
    <!-- Jedis ConnectionFactory -->
    <bean 
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
        p:hostName="${redis.url}" p:port="${redis.port}" p:password="${redis.password}" p:pool-config-ref="poolConfig"/>
    <bean 
        class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
    <bean 
        class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer">
    </bean>

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

  假如要使用redis驱动lua脚本则需要加入类似的配置

<bean  class="org.springframework.data.redis.core.script.DefaultRedisScript">
        <property name="location" value="classpath:META-INF/lua/updateAvailableSavingsCard.lua"/>
        <property name="resultType" value="org.meibaobao.ecos.basecomponent.common.Result"/>
    </bean>
    <bean  class="org.springframework.data.redis.core.script.DefaultRedisScript">
        <property name="location" value="classpath:META-INF/lua/initAvailableSavingsCard.lua"/>
        <property name="resultType" value="java.lang.Boolean"/>
    </bean>

  lua脚本文件(updateAvailableSavingsCard.lua)

-- 操作可用储蓄卡,当客户购买则减,卖家增加可用库存则加,使用lua脚本redis操作的保证原子性
redis.call('INCRBY', KEYS[1], ARGV[1])
local current = redis.call('GET', KEYS[1])
local result ={}
result["@class"] = "org.meibaobao.ecos.basecomponent.common.Result"
if tonumber(current)<0
then
    redis.call('DECRBY', KEYS[1], ARGV[1])
    current = redis.call('GET', KEYS[1])
    result["success"] = false
    result["data"] = current
    local encodestr = cjson.encode(result)
    print(encodestr)
    return  encodestr
end
result["success"] = true
result["data"] = current
local encodestr = cjson.encode(result)
print(encodestr)
return  encodestr

3.资源文件

#redis
redis.url=10.72.82.124
redis.port=6379
redis.password=

redis.maxIdle=200
redis.maxActive=1024
redis.maxWait=1000
redis.testOnBorrow=true

4.java代码

package org.meibaobao.ecos.storedCard.scheme.service.component.impl;

import java.util.Collections;

import javax.annotation.Resource;

import org.meibaobao.ecos.basecomponent.common.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

/**
 * 储蓄卡资源
 *
 */
@Service
public class StoredCardInventoryServiceImpl {
    @Resource(name = "updateAvailableSavingsCard")
    RedisScript<Result> updateAvailableSavingsCard;
    @Resource(name = "initAvailableSavingsCard")
    RedisScript<Boolean> initAvailableSavingsCard;
    
    @Autowired
    RedisTemplate<String,Integer> redisTemplate;
    
    public static String availableStotredCardInventoryNamePre = "availableStotredCard_";
    /**
     * 操作可用资源
     */
    public Result availableStotredCardInventory(String storedCardSchemeNo,int num){
        return redisTemplate.execute(updateAvailableSavingsCard,  Collections.singletonList(availableStotredCardInventoryNamePre+storedCardSchemeNo),num);
    }
    /**
     * 初始化可用资源
     */
    public Boolean initAvailableStotredCardInventory(String storedCardSchemeNo,int num){
        return redisTemplate.execute(initAvailableSavingsCard,  Collections.singletonList(availableStotredCardInventoryNamePre+storedCardSchemeNo),
                num);
    }
}

5.junit4单元测试代码

package org.meibaobao.ecos.storedCard.scheme.service.component.impl;

import java.util.Map;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:development/xml/spring/applicationContext.xml" })
public class StotredCardInventoryServiceImplTest {
    
    @Resource
    private StoredCardInventoryServiceImpl stotredCardInventoryServiceImpl;
    
    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    
    @Test
    public void availableStotredCardInventory() {
        System.out.println(stotredCardInventoryServiceImpl.initAvailableStotredCardInventory("test1111112",-10));
        System.out.println(stotredCardInventoryServiceImpl.initAvailableStotredCardInventory("test1111112",-10));
        
        redisTemplate.opsForValue().set("test99999", "123asd");
        
        System.out.println(redisTemplate.opsForValue().get("test99999"));    
        
        
        //测试hash
        String key = "hashtest11";
        redisTemplate.opsForHash().put(key, "name1", "11");
        redisTemplate.opsForHash().put(key, "name2", "22");
        redisTemplate.opsForHash().put(key, "name3", "33");
        
        System.out.println(redisTemplate.opsForHash().get(key, "name2"));
        redisTemplate.opsForHash().delete(key, "name2");
        System.out.println(redisTemplate.opsForHash().get(key, "name2"));
        System.out.println(redisTemplate.opsForHash().get(key, "name1"));
        
        Map<Object, Object> opsMap = redisTemplate.opsForHash().entries(key);
        if(opsMap != null) {
            System.out.println(opsMap.keySet());
            System.out.println(opsMap.values());
            for(Object object : opsMap.keySet()) {
                System.out.println(object + "," + opsMap.get(object));
            }
        }
    }
    
    
}