使用redis和spring集成实际中遇到的问题

最近使用redis遇到一些问题,记录一下。
格式就不排了,有时间再弄吧。

一、版本信息
spring 4.2.5
mysql 5.1.18
mybatis 3.2.8
mybatis-spring 1.2.4
jedis 2.8.0
spring-data 1.7.1
... ...


二、jedis和spring集成
1. 配置数据源

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="minIdle" value="${redis.minIdle}" />
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!--对拿到的connection进行validateObject校验 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
<!--在进行returnObject对返回的connection进行validateObject校验 -->
<property name="testOnReturn" value="${redis.testOnReturn}" />
<!--定时对线程池中空闲的链接进行validateObject校验 -->
<property name="testWhileIdle" value="${redis.testWhileIdle}" />
</bean>

<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.default.database}" />
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
<bean id="redis4CacheConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.cache.database}" />
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>


2.配置Template

<bean id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<property name="keySerializer" ref="stringRedisSerializer" />
<property name="hashKeySerializer" ref="stringRedisSerializer" />
<!-- 默认即为 jdkRedisSerializer -->
<!-- <property name="valueSerializer" ref="jdkRedisSerializer" />
<property name="hashValueSerializer" ref="jdkRedisSerializer" /> -->
<!-- <property name="enableTransactionSupport" value="true" /> -->
</bean>

注:在spring事务中不执行Lua脚本可使用enableTransactionSupport,否则报java.lang.unsupportedclassversion

三、与springCache集成

<bean id="redis4CacheTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redis4CacheConnectionFactory" />
<property name="keySerializer" ref="stringRedisSerializer" />
</bean>

<!-- 开启缓存注解 -->
<cache:annotation-driven/>

<!-- declare Redis Cache Manager -->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redis4CacheTemplate" />
<!-- 是否事务提交,如果事务回滚,缓存也回滚,默认false -->
<property name="transactionAware" value="true" />
<!-- 默认有效期1d 3600*24 -->
<property name="defaultExpiration" value="86400" />
</bean>



public abstract class BaseCache {
public String generateKey(String... args) {
return RedisUtil.generateKey(args);
}
@CacheEvict(allEntries = true)
public abstract void clearCaches(Class<?> clazz);
}

@Component(ActivityCache.SERVICE_NAME)
@CacheConfig(cacheNames = {ActivityCache.SERVICE_NAME})
public class ActivityCache extends BaseCache {

/**
* SERVICE_NAME:服务名
*/
public static final String SERVICE_NAME = "activityCache";

@Autowired
private ActivityDao activityDao;
@Cacheable(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activityCode)",
unless="#result == null")
public Activity getActivityInfo(String activityCode){
Activity activity = null;
try {
} catch (Exception e) {
log.error(e.getMessage(),e);
}
return activity;
}

@CachePut(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activity.activityCode)",
unless="#result == null")
public Activity saveOrUpdateActivityInfo(Activity activity)

@CachePut(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activityCode)",
unless="#result == null")
public int delActivity(String activityCode)

@CacheEvict(allEntries = true)
public void clearCaches(Class<?> clazz)

}


四、关于取值异常问题

Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/spring.xml"
// ,
// "classpath:spring/spring-mvc.xml",
// "file:src/main/java/com/sinowel/eacpc/**/mapping/*.xml"
})
public class TestBase {

@Before
public void setUp() throws Exception {
}

}



public class TestLua2 extends TestBase {
private final Logger logger = LoggerFactory.getLogger(TestLua2.class);

@Resource(name = RedisService.SERVICE_NAME)
private RedisService redisService; // redis

@Resource(name = "redisTemplate")
private RedisTemplate<String, Object> redisTemplate; // redis

@Test
public void testInject() throws Exception {
// 在服务器redis-cli连接预存入Hash key=tt1 field=t1,t2的数值
String redisKey = "tt1";
List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
List<Long> list = redisService.getMultiHash(redisKey, fieldList, null);
System.out.println(list.get(0).longValue());

// 存入时使用stringRedisSerializer,取值时使用jdkRedisSerializer。xml RedisTemplate时配置
// 异常,先存,再次取,配置文件切换配置
String redisKey = "tt2";
List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
redisService.setHash(redisKey, "t1", "1");
redisService.setHash(redisKey, "t2", "2");
BoundHashOperations<String, String, Long> bhOps = redisTemplate
.boundHashOps(redisKey);
List<Long> list = bhOps.multiGet(fieldList);
System.out.println(list.get(0));

// keySerializer 和 hashKeySerializer 设置 stringRedisSerializer
// valueSerializer 和 hashValueSerializer 设置成默认 jdkRedisSerializer
// 则可以取得指定值,否则都使用stringRedisSerializer,取到的值一定是String类型
String redisKey = "tt3";
List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
BoundHashOperations<String, String, Long> bhOps = redisTemplate
.boundHashOps(redisKey);
bhOps.put("t1", 1L);
bhOps.put("t2", 2L);
List<Long> list = bhOps.multiGet(fieldList);
System.out.println(list.get(0));
}
}


redis-cli取到序列化后的值【1】
stringRedisSerializer:
"\xac\xed\x00\x05t\x00\x011"

jdkRedisSerializer:
"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01"

总结:各个RedisSerializer序列化的值存入redis后,取值时,是不能切换取值的。因为序列化方式不同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值