1 简介
Redis是一个基于内存的Key-Value数据库。Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
Redis存储的所有元素都是字符串(二进制安全的,意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象),所以如果我们想存储Java对象,那么我们需要把Java对象转换为字符串。
Spring提供了序列化的设计框架和一些序列化类,使用后它可以通过序列化把Java对象转换,使Redis能把它存储起来,并在读取的时候,再把序列化过的字符串转化为Java对象。
2 在Java中使用Redis
- 依赖包: jedis.jar
- 依赖包:commons-pool2-2.3.jar
2.1 直接获取Redis的连接
Jedis jedis = new Jedis("localhost", 6379);
// jedis.auth("password"); // 如果需要密码的话
jedis.set("msg", "hello world");
String msg = jedis.get("msg");
System.out.println(msg); // hello world
jedis.close();
2.2 使用Redis连接池
public static JedisPool pool() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(50); // 最大空闲数
poolConfig.setMaxTotal(100); // 最大连接数
poolConfig.setMaxWaitMillis(10000);
JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379);
return jedisPool;
}
// 测试:
Jedis jedis = pool().getResource();
jedis.set("msg", "good");
String msg = jedis.get("msg");
System.out.println(msg);
jedis.close();
3 在Spring中使用Redis
- 依赖包: spring-data-redis.jar
3.1 使用RedisTemplate操作Redis
1 使用注解配置Spring
@Configuration
@ComponentScan
public class AppConfig {
/**
Redis连接池配置
*/
@Bean
public JedisPoolConfig initJedisPoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(50);
poolConfig.setMaxTotal(100);
poolConfig.setMaxWaitMillis(10000);
return poolConfig;
}
@Bean
public RedisConnectionFactory initRedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName("localhost");
factory.setPort(6379);
factory.setPoolConfig(initJedisPoolConfig());
return factory;
}
@Bean
public RedisTemplate initRedisTemplate() {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(initRedisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return redisTemplate;
}
}
2 要存储的对象(要实现Serializable接口)
public class Role implements Serializable{
/**
*
*/
private static final long serialVersionUID = 8980813184458792099L;
private int id;
private String roleName;
private String note;
// get set
}
3 测试
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
Role role = new Role();
role.setId(10);role.setRoleName("张华");role.setNote("好人");
redisTemplate.opsForValue().set("role", role);
Role role2 = (Role) redisTemplate.opsForValue().get("role");
System.out.println(role2); // Role [id=10, roleName=张华, note=好人]
}
4 注:
redisTemplate.opsForValue().set("role", role);
Role role2 = (Role) redisTemplate.opsForValue().get("role");
上述两次操作,不能保证redisTemplate是操作同一个对Redis的连接
5 为了是所有操作都来自同一个连接,我们可以使用SessionCallback接口。如下:
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
Role role = new Role();
role.setId(10);role.setRoleName("张华");role.setNote("好人");
SessionCallback<Role> sessionCallback = new SessionCallback<Role>() {
@Override
public Role execute(RedisOperations ops) throws DataAccessException {
ops.boundValueOps("role").set(role); // 1
return (Role) ops.boundValueOps("role").get(); // 2
}
};
Role role2 = (Role) redisTemplate.execute(sessionCallback);
System.out.println(role2);
上述标记的操作 1, 2 都来自同一个连接。