SpringBoot Redis篇 (三)
上篇文章介绍了SpringBootWeb:SpringBoot Web篇(二),方便大家快速入门、了解实践SpringBoot特性。本篇文章为大家介绍SpringBoot整合Redis。
一、Redis简介
Redis是一个高性能的key-value数据库。它支持存储的value类型很多,包括String(字符串)、List(列表)、Set(集合)、Sorted-Set(有序集合)和Hash(哈希类型)。
二、搭建前记
工具:Eclipse。
项目工程:maven工程
项目结构图:
三、搭建步骤
1、添加pom.xml文件
<!-- Spring Boot Redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、 添加配置文件
### Redis服务器地址
spring.redis.host=101.201.210.31
### Redis服务器连接端口
spring.redis.port=6379
### Redis服务器连接密码(默认为空)
spring.redis.password=1234
### 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
### 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=10000
### 连接池中的最大空闲连接
spring.redis.pool.max-idle=80
### 连接池中的最小空闲连接
spring.redis.pool.min-idle=10
### 连接超时时间(毫秒)
spring.redis.timeout=5000
3、在UserServiceImpl 类中向Redis添加操作。
/**
* 获取用户逻辑: 如果缓存存在,从缓存中获取用户信息
* 如果缓存不存在,从 DB 中获取用户信息,然后插入缓存
*/
@Override
public User findUserById(Long id) {
User user = null;
String key = "user_key_" + id;
ValueOperations<String, String> ops = redisTemplate.opsForValue();
Boolean flag = redisTemplate.hasKey(key);
// 缓存存在
if (flag) {
Object object = ops.get(key);
user = JsonUtils.json2Object(object.toString(), User.class);
} else {
// 缓存不存在,查询数据库,并把信息存进缓存里
Optional<User> optionalUser = userDao.findById(id);
if (null != optionalUser) {
user = optionalUser.get();
ops.set(key, JsonUtils.object2Json(user));
//设置过期时间
//ops.set(key,JsonUtils.object2Json(user),1,TimeUnit.MINUTES);
}
}
return user;
}
4、使用RedisTempate类
/**
* Redis缓存工具类
*/
@Autowired
private RedisTemplate<String, String> redisTemplate;
5、UserController类
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
/**
* 通过id 查询User对象
*
* @param id
* @return
*/
@RequestMapping(value = "/api/findinfo/{id}")
public User findUserById(@PathVariable("id") Long id) {
return userService.findUserById(id);
}
/**
* 保存用户信息
*
* @param user
*/
@RequestMapping(value = "/api/create")
public void saveUser(User user) {
userService.saveUser(user);
}
/**
* 更改用户信息
*
* @param user
*/
@RequestMapping(value = "/api/modify")
public void updateUser(User user) {
userService.updateUser(user);
}
/**
* 删除用户信息
*
* @param id
*/
@RequestMapping(value = "/api/delete/{id}")
public void deleteUser(@PathVariable("id") Long id) {
userService.deleteUser(id);
}
}
6、测试结果
四、RedisTemplate类
1、RedisTemplate中定义了对5种数据结构操作:
//操作字符串
redisTemplate.opsForValue();
//操作hash
redisTemplate.opsForHash();
//操作list
redisTemplate.opsForList();
//操作set
redisTemplate.opsForSet();
//操作有序set
redisTemplate.opsForZSet();
其他方法请参考官方Api:
https://docs.huihoo.com/javadoc/spring/spring-data/redis/1.0/org/springframework/data/redis/core/RedisTemplate.html
2、StringRedisTemplate(SRT)与RedisTemplate(RT)区别?
两者的关系是SRT继承RT。
两者的数据是不共通的;也就是说SRT只能管理SRT里面的数据,RT只能管理RT中的数据。
SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
SRT默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
RT默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
五、常见问题
1、RedisTemplate数据存储产生的序列化问题?
通过RedisTemplate的opsForValue的set方法把数据存入缓存,在Redis客户端取不出数据。
存入客户端的的数据为:
2、数据已经被序列化
RedisTemplate中set值时会先调用序列化器将键和值都序列化byte字节数组放入Redis数据库中,在客户端除非get后的key为“user_key_1”使用同样的序列化器,进行取值,否则取不到值。原因是ReidsTemplate使用的默认的序列化方式有问题。
解决方法:
新增RedisSerializeConfig类。
@Component
public class RedisSerializeConfig {
@Autowired
protected RedisTemplate<String, String> redisTemplate;
@PostConstruct
private void init() {
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
}
}