四、StringRedisTemplate 和 RedisTemlate 有什么不同
关于二者优缺点,我们先来看一个例子:
还是上一篇博客的源代码,RedisService 层使用的是 RedisTemplate,界面上存取,显示都没有问题,这里重点关注一下,getUser(),我这里强转 User,在界面上可以正常显示。
@Autowired
private RedisTemplate redisTemplate;
public boolean setUser(User user){
ValueOperations ops=redisTemplate.opsForValue();
ops.set(user.getNickname(),user);
return true;
}
public User getUser(String name){
ValueOperations ops=redisTemplate.opsForValue();
return (User)ops.get(name);
}
那我们再使用 StringTemplate
修改 RedisService 层
@Autowired
private StringRedisTemplate stringRedisTemplate;
public boolean setUser(User user){
ValueOperations ops=stringRedisTemplate.opsForValue();
ops.set(user.getNickname(),user);
return true;
}
public User getUser(String name){
ValueOperations ops=stringRedisTemplate.opsForValue();
return (User)ops.get(name);
}
再来实行 set 和 get 就会报错。
set 方法报错,说明不能将一个对象直接当做 value 值传过去,没有进行转换。而 RedisTemplate 却可以直接把对象当做 value 值存进去了。因为 RedisTemplate 在写入和读出的时候都进行了转换。
被逼无奈的修改了代码如下;
RedisController 层
@RestController
public class RedisController {
@Autowired
private RedisService redisService;
@RequestMapping("/getUser")
public User getUser(){
String name="quellan";
return redisService.getUser(name);
}
@RequestMapping("/setUser")
public String setUser(){
User user=new User("aa@qq.com","quellan","123456","朱",new Date().getTime()+"");
redisService.setUser(user);
user.setEmail("bb@qq.com");
redisService.setUserBystringRedisTemplate(user);
return "添加成功";
}
@RequestMapping("/getUserByStringRedisTemplate")
public String getUserByStringRedisTemplate(){
String name="quellan";
return redisService.getUserBystringRedisTemplate(name);
}
}
RedisService 层
@Service
@Slf4j
public class RedisService {
@Autowired
pr
ivate RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
public boolean setUser(User user){
ValueOperations ops=redisTemplate.opsForValue();
ops.set(user.getNickname(),user);
return true;
}
public User getUser(String name){
ValueOperations ops=redisTemplate.opsForValue();
return (User)ops.get(name);
}
public boolean setUserBystringRedisTemplate(User user){
ValueOperations ops=stringRedisTemplate.opsForValue();
ops.set(user.getNickname(),JSONObject.fromObject(user).toString());
return true;
}
public String getUserBystringRedisTemplate(String name){
ValueOperations ops=stringRedisTemplate.opsForValue();
return JSONObject.fromObject(ops.get(name)).toString();
}
}
server 层就是分别使用 RedisTemplate 和 StringRedisTemplate 对 User 对象进行存和读的操作。特别注意一下 StringRedisTemplate 由于直接对象不能存,所以先转成 string 才能存进去的,读出来的时候,也是 string 形式返回的,如果读出来想要变成 user 类还得进一步转换。
来看看效果现在。先 setUser,往 redis 中插入两条数据,这里可以看到我们代码中设置的 key 是一样的,都是 quellan
来看看获取结果 getUser 是使用 RedisTemplate 来获取的,邮箱是 aa
来看看 getUserByStringRedisTemplate,邮箱是 bb
这里是不是有说明了一个问题:使用 RedisTemplate 和 StringRedisTemplate 是相互独立的,在代码中使用相同的 key 值进行存储,不会替换,两份都会存在,具体原因还是刚刚提到的,其实他们真实存在 redis 数据库的 key 是不一样的,所以才会独立。我们看看 redis 数据库。
可以发现 redis 数据库中有两个 key 值,其中 key 值为 quellan 的是使用 stringRedisTemplate 来来存储的,可以看到邮箱为 bb。还有一个乱码的 key 值使用 RedisTemplate 存储的,在控制台怎么获取这个 key 值我暂时也不知道,有知道的小伙伴希望告知一下,嘿嘿。
上面说的 redisTemplate 和 StringRedisTemplate 是独立的,这个在项目中很容易出现坑的,所以小伙伴们得多多注意,不要存的时候用 StringRedisTemplate 读的时候用 redisTemplate 或者相反。这样可能回到导致死活读不出数据。
================================================================
上面说了这么多,总结一下吧:
1、RedisTemplate 和 StringRedisTemplate 存储是分开存的,也就是代码中相同的 key 实际上在 redis 数据库中有两个 key.原因是 RedisTemplate 进行了转换,而 StringRedisTemplate 直接以代码 key 值存储了。
2、如果我们存一些简单的数据结构,建议使用 StringRedisTemplate,因为方便在数据库中查看。如果我们存一些复杂的数据接口,比如对象里面还包含多个对象的,就建议使用 RedisTemplate 了,系统会帮忙转换,省去我们自己转换的麻烦,上面的代码可以看到直接将取到的 value 值强转成 user 都没问题,很方便。
3、二者可以配合使用,但是不能混着用。
================================================================
刚刚我们在控制台 get quellan
的时候发现 userName 是乱码的。
那是因为我们进入的方式不对。需要用
redis-cli --raw -a password
评论