使用步骤
配置文件, 只需要配置了 redisTemplate 就可以
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath:config.properties" /> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.pool.maxActive}" /> <property name="maxIdle" value="${redis.pool.maxIdle}" /> <property name="maxWaitMillis" value="${redis.pool.maxWait}" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> </bean> <bean id="connectionFactory" 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.database}"/> <property name="poolConfig" ref="jedisPoolConfig"/> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="connectionFactory" /> <property name="keySerializer" ref="keySerializer"/> <!-- key使用String序列化方式 --> <property name="hashKeySerializer" ref="keySerializer"/> <property name="valueSerializer" ref="jackson2JsonRedisSerializer"/> <!-- value使用json序列化 --> <property name="hashValueSerializer" ref="jackson2JsonRedisSerializer"/> <!--<property name="hashValueSerializer" ref="jdkSerializer"/>--> </bean> <bean id="keySerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> <bean id="jackson2JsonRedisSerializer" class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/> <bean id="jdkSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> </beans>
测试
package com.susq.redisdb; import com.susq.mysqldb.model.User; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; /** * @author susq * @since 2018-05-16-20:35 */ SpringJUnit4ClassRunner.class) (value = "classpath:spring-cache.xml") (public class RedisTemplateApp { private RedisTemplate<String, User> redisTemplate; /*redisTemplate.opsForValue()默认使用了redisTemplate配置的序列化方式*/ public void putUser() { User user = new User("haha", "hangzhou"); redisTemplate.opsForValue().set(user.getName(), user, 10, TimeUnit.SECONDS); User user1 = redisTemplate.opsForValue().get(user.getName()); log.info(user1.toString()); } public void getUser() { User user = redisTemplate.opsForValue().get("haha"); if (null == user) { log.info("不存在的"); return; } log.info(user.toString()); } public void putUserSer() { User user = new User("haha", "hangzhou"); redisTemplate.execute(new RedisCallback<User>() { public User doInRedis(RedisConnection redisConnection) throws DataAccessException { RedisSerializer<String> keySerializer = redisTemplate.getStringSerializer(); RedisSerializer<User> valueSerializer = (RedisSerializer<User>) redisTemplate.getValueSerializer(); byte[] keyBytes = keySerializer.serialize(user.getName()); byte[] valueBytes = valueSerializer.serialize(user); redisConnection.setEx(keyBytes, 20, valueBytes); byte[] value = redisConnection.get(keyBytes); User user1 = valueSerializer.deserialize(value); log.info("put结束后,再get出来验证:{}", user1); return null; } }); // 这个操作封装了获取value的字节后反序列化的操作,跟上面的先get得到byte[]再deserialize的到对象一样 User user1 = redisTemplate.opsForValue().get(user.getName()); log.info(user1.toString()); } }
redisTemplate.execute() 可以自己实现 RedisCallback 接口,更灵活一些。而直接使用redisTemplate.opsForValue(),redisTemplate.opsForHash()..... 这样的形式更方便简洁。
为什么序列化?
作者:大宽宽
链接:https://www.zhihu.com/question/277363840/answer/392945240
任何存储都需要序列化。只不过常规你在用DB一类存储的时候,这个事情DB帮你在内部搞定了(直接把SQL带有类型的数据转换成内部序列化的格式,存储;读取时再解析出来)。
而Redis并不会帮你做这个事情。当你用Redis的key和value时,value对于redis来讲就是个byte array。你要自己负责把你的数据结构转换成byte array,等读取时再读出来。
一个特例是字符串,因为字符串自己几乎就已经是byte array了,所以不需要自己处理。
因此当你要用redis存一个东西,你可能会遇到
如果是boolean类型的true/false;你要自己定义redis里怎么表示true和false。比如你可以用1代表true,0代表false;也可以用“true”这个字符串代表true,“false”这个字符串代表false。
如果是数字,可以直接存储数字的字符串表示(5 --> '5'),然后读取时再把数字字符串转回来(parseInt/parseDouble/...)。
如果是时间/日期,可以自己定义一种字符串表达,比如epoc timestamp这个数的字符串表示,又或者是ISO8601的格式。
如果是一个复杂的数据结构,你需要自己用某种序列化格式来存,可以是json, protobuf, avro, java serialization, python pickle……
回到Spring这边。Spring的redisTemplate默认会使用java serialization做序列化。你也可以用StringRedisTemplate,那么你set的所有数据都会被toString一下再存到redis里。但这个toString不一定能反解析的回来……
其他
spring @Cacheable @CachePut... 使用redis缓存详细步骤