一 jedis配置实例(必须使用pool, 否则线程不安全)
@ConfigurationProperties(prefix = "jedis")
@Component
@Data
public class JedisProperties {
private String host;
private int port;
private String password;
private int database;
private int maxActive;
private int maxIdle;
private int minIdle;
private int maxWait;
}
@Autowired
private JedisProperties jedisProperties;
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(jedisProperties.getMaxIdle());
jedisPoolConfig.setMinIdle(jedisProperties.getMinIdle());
jedisPoolConfig.setMaxTotal(jedisProperties.getMaxActive());
jedisPoolConfig.setMaxWaitMillis(jedisProperties.getMaxWait());
return jedisPoolConfig;
}
@Bean
public JedisShardInfo jedisShardInfo(){
JedisShardInfo jedisShardInfo = new JedisShardInfo(jedisProperties.getHost(), jedisProperties.getPort());
jedisShardInfo.setPassword(jedisProperties.getPassword());
return jedisShardInfo;
}
@Bean
public RedisConnectionFactory jedisConnectionFactory(){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisShardInfo());
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.setUsePool(true);
return jedisConnectionFactory;
}
@Bean
public RedisTemplate<String, Object> jedisTemplate(){
RedisTemplate<String, Object> jedisTemplate = new RedisTemplate<>();
jedisTemplate.setConnectionFactory(jedisConnectionFactory());
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
jedisTemplate.setKeySerializer(stringRedisSerializer);
jedisTemplate.setHashKeySerializer(stringRedisSerializer);
// value 序列化器
// GenericToStringSerializer<Object> genericToStringSerializer = new GenericToStringSerializer<>(Object.class);
// jedisTemplate.setValueSerializer(genericToStringSerializer);
// jedisTemplate.setHashValueSerializer(genericToStringSerializer);
//
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
jackson2JsonRedisSerializer.setObjectMapper(new ObjectMapper());
jedisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
jedisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
// jedisTemplate.afterPropertiesSet();
return jedisTemplate;
}
lettuce配置实例 (底层是netty, 可以是单个连接, 不用连接池)
@Bean
public RedisConnectionFactory redisConnectionFactory(){
LettuceConnectionFactory factory = new LettuceConnectionFactory(
"192.168.126.4", 6379);
factory.setPassword("Password01!");
return factory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value 序列化器
// GenericToStringSerializer<Object> genericToStringSerializer = new GenericToStringSerializer<>(Object.class);
// redisTemplate.setValueSerializer(genericToStringSerializer);
// redisTemplate.setHashValueSerializer(genericToStringSerializer);
//
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
jackson2JsonRedisSerializer.setObjectMapper(new ObjectMapper());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
// redisTemplate.afterPropertiesSet();
return redisTemplate;
}
二 lua脚本(独占的分布式锁, 设置释放时间, jedis和 lettuce都可用)
// 注: 使用lua脚本, 涉及 ARGV参数为数字的, 值序列化器必须不能是默认的jdk序列化
// 具体可在RedisDeskTopManager客户端看下, jdk序列化后的值是什么样
@GetMapping("testLua/{key}/{value}/{pexpire}")
public Number testLua(@PathVariable("key") String key,
@PathVariable("value") String value,
@PathVariable("pexpire") long pexpire) {
String lua = "local key=KEYS[1] \n" +
"local result=redis.call('setNX', key, ARGV[1])\n" +
"if(1==tonumber(result)) then redis.call('pexpire',key,ARGV[2]) end \n" +
"return tonumber(result)";
RedisScript<Number> redisScript = new DefaultRedisScript<>(lua, Number.class);
Number result = redisTemplate.execute(redisScript, Lists.newArrayList(key),
value, pexpire);
return result;
}
三 jackson序列化, 指定ObjectMapper
// RedisTemplate<String,Object>, 直接序列化对象到redis
@Test
public void test01(){
ObjectMapper mapper = new ObjectMapper();
redisUtils.set("kk", new Stu("zzy", 12));
List<Stu> strList = Lists.newArrayList(
new Stu("sd", 1),
new Stu("sdkjf", 1)
);
redisUtils.set("st", strList);
// 反序列化value, 通过 ObjectMapper
try {
Stu stu = mapper.readValue(mapper.writeValueAsString(redisUtils.get("kk")), Stu.class);
CollectionType javaType = mapper.getTypeFactory().constructCollectionType(
List.class, Stu.class
);
List<String> list = mapper.readValue(mapper.writeValueAsString(redisUtils.get("st")), javaType);
System.err.println(stu);
System.err.println(list);
} catch (IOException e) {
e.printStackTrace();
}
}
四 pipeLine操作, jedis和 lettuce都可用
@Test
public void testPipe(){
RedisSerializer<String> keySerializer = (RedisSerializer<String>) jedisTemplate.getKeySerializer();
RedisSerializer<Object> valueSerializer = (RedisSerializer<Object>) jedisTemplate.getValueSerializer();
jedisTemplate.executePipelined(new RedisCallback<Object>() {
String key = "k";
Object value = "v";
String key1 = "k1";
String value1 = "v1";
String value2 = "v2";
String value3 = "v3";
long ttl = 60 * 60;
@Override
public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
redisConnection.set(keySerializer.serialize(key), valueSerializer.serialize(value),
Expiration.seconds(ttl), RedisStringCommands.SetOption.UPSERT);
redisConnection.zIncrBy(keySerializer.serialize(key1), 6.6, valueSerializer.serialize(value1));
redisConnection.zIncrBy(keySerializer.serialize(key1), 3.4, valueSerializer.serialize(value2));
redisConnection.zIncrBy(keySerializer.serialize(key1), 6.8, valueSerializer.serialize(value3));
redisConnection.expire(keySerializer.serialize(key1), 1000);
return null;
}
});
}