redis是一个很强大的缓存工具,那么,在Java项目中如何使用呢?
redis连接驱动,使用的最多的目前应该是Jedis。
在maven中央仓库搜索jedis
最新是3.3.0。
spring提供了一个RedisConnectionFactory的接口,通过它可以生成一个RedisConnection接口对象,而RedisConnection接口对象是对Rediis底层接口的封装。
这是RedisConnection相关的结构图
简化下:
在spring中是通过RedisConnection接口操作Redis的,而RedisConnection则对原生的Jedis进行封装。要获取RedisConnection接口对象,是通过RedisConnectionFactory接口去生成的,所以第一步需要配置RedisConnectionFactory。
首先创建一个配置类:
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String hostname;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.database}")
private int database;
private RedisConnectionFactory factory = null;
@Bean("redisConnectionFactory")
public RedisConnectionFactory initConnectionFactory() {
if (factory != null) {
return factory;
}
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 最大空闲数
poolConfig.setMaxIdle(10);
// 最大连接数
poolConfig.setMaxTotal(25);
// 最大等待毫秒数
poolConfig.setMaxWaitMillis(timeout);
// 创建连接工厂
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig);
// 获取单机的Redis配置
RedisStandaloneConfiguration rsConfig = jedisConnectionFactory.getStandaloneConfiguration();
rsConfig.setHostName(hostname);
rsConfig.setPort(port);
rsConfig.setPassword(password);
rsConfig.setDatabase(database);
factory = jedisConnectionFactory;
return factory;
}
}
配置文件:
spring:
redis:
host: 10.0.228.117
port: 6379
password: ""
timeout: 2000
database: 0
通过一个连接池创建了RedisConnectionFactory,通过factory创建RedisConnection对象。再试用的时候,要先从RedisConnectionFactory工厂获取,然后使用,使用完成后,需要手动关闭。
我们在test方法中尝试用下:
执行testFactory方法
然后使用客户端连接查看
单纯的使用RedisConnection,每次使用前需要获取连接,使用完需要释放连接,如果忘记释放,那么很快就会耗尽redis连接池的连接。
所以,spring提供了RedisTemplate
ok,我们继续尝试,首先是创建RedisTemplate
@Bean("redisTemplate")
public RedisTemplate initRedisTemplate() {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(initConnectionFactory());
return template;
}
然后在test中尝试使用:
执行结果:
发现并没有输出,我们使用客户端查看
咦,我们给的key是test,为什么存储后是xxxxtest呢?
Redis是给予字符串存储的NoSql,而Java是基于帝乡的语言,对象是无法存储到Redis中的,不过Java提供了序列化机制,只要类实现了Serializable接口,就代表能够进行序列化。通过将类对象进行序列化就能得到二进制字符串,然后Redis就可以将类对象以字符串的方式进行存储。java也可以将二进制字符串,进行反序列化转为对象。Spring提供了序列化器的机制,并实现了几个序列化器。
这是spring实现的序列化器
RedisTemplate中可以配置的序列化器
属性 | 描述 | 备注 |
---|---|---|
defaultSerializer | 默认序列化器 | 如果没有设置,则使用JdkSerializationRedisSerializer |
keySerializer | Redis键序列化器 | 如果没有设置,则使用默认序列化器 |
valueSerializer | Redis值序列化器 | 如果没有设置,则使用默认序列化器 |
hashKeySerializer | Redis Hash field序列化器 | 如果没有设置,则使用默认序列化器 |
hashValueSerializer | Redis Hash value序列化器 | 如果没有设置,则使用默认序列化器 |
stringSerializer | 字符串序列化器 | RedisTemplate自动赋值为StringRedisSerializer |
因为我们对RedisTemplate什么样的序列化器都没有配置,所以使用默认的JdkSerializationRedisSerializer进行序列化和反序列化,也就是说,将字符串按照对象进行序列化了,所以我们设置的键前面还有一些字符。
我们将RedisTemplate的序列化器指定为stringSerializer.
然后重新执行
然后查看redis:
忘记设置valueSerializer了
Redis能够支持7种类型的数据结构,常用的5种数据结构:string,hash,list,set,sorted set
redisTemplate获取数据类型操作接口:
redis数据结构 | 操作接口获取 |
---|---|
string | redisTemplate.opsForValue() |
hash | redisTemplate.opsForHash() |
list | redisTemplate.opsForList() |
set | redisTemplate.opsForSet() |
sorted set | redisTemplate.opsForZSet() |
同样的,在spring中,也支持对某一个key进行批量操作:
redisTemplate对批量操作的支持:
redis数据类型 | spring批量操作的封装 |
---|---|
string | redisTemplate.boundValueOps(“key”) |
hash | redisTemplate.boundHashOps(“key”) |
list | redisTemplate.boundListOps(“key”) |
set | redisTemplate.boundSetOps(“key”) |
sorted set | redisTemplate.boundZSetOps(“key”) |
RedisTemplate的回调
通过使用回调,可以在同一个连接下执行多个Redis命令。
其中SessionCallback比RedisCallback拥有更多的封装,使用起来更加友好。
SessionCallback
@Test
public void testRedisSessionCallback() {
redisTemplate.execute((RedisConnection rc) -> {
rc.set("session1".getBytes(), "session1".getBytes());
rc.set("session2".getBytes(), "session2".getBytes());
return null;
});
}
RedisCallback
@Test
public void testRedisCallback() {
redisTemplate.execute((RedisConnection rc) -> {
rc.set("redis1".getBytes(), "redis1".getBytes());
rc.set("redis2".getBytes(), "redis2".getBytes());
return null;
});
}