最近刚在项目里接触redis,结果发现各种各样对redis进行操作的方式,比如RedisTemplate,Jedis等等,好像对redis操作起来都挺方便,但是很好奇它们之间的区别是啥,于是看了不少资料,终于整理出来跟大家分享
Jedis是Redis官方推荐的面向Java的操作Redis的客户端,听起来好像很牛逼…那么怎么来使用它呢??
redis.clients
jedis
3.1.0
public static void main(String[] args){
Jedis jedis = new Jedis("192.168.0.110",6379);
jedis.set("hello","world");
System.out.println(jedis.get("hello"));
}
当然,这里如果不指定ip和port也可以,只不过为默认的ip和port,可以看源码如下:(BinaryJedis是Jedis的父类
public BinaryJedis() {
this.client = null;
this.transaction = null;
this.pipeline = null;
this.dummyArray = new byte[0][];
this.client = new Client();
}
(Connection是Client的父类,可以看到默认的ip和port
public class Connection implements Closeable {
private static final byte[][] EMPTY_ARGS = new byte[0][];
private String host = "localhost";
private int port = 6379;
//此处省略...
}
可以看到jedis的使用还是很简单的呢…但是直接使用new的方式获取对象好像有点low…
而且需要注意的是!!!Jedis并不是线程安全的,在多线程使用同一个Jedis对象的时候会发生并发问题…这个时候JedisPool就出场啦
JedisPool类似于各种线程池,以及连接池,它是一个管理Jedis对象的池子,使Jedis对象恰到好处地被利用,既不过多创建,也不过少创建而导致多线程并发问题
那么它如何被使用呢???其实也很简单(当然有更复杂地需求另说啦…这里讲解的使用方法只是方便小白快速上手,需要更复杂的配置也可以评论区走起呀…我后续再出更复杂全面的JedisPool配置方式
需要的依赖同上~
public static void main(String[] args){
//这里也可以省略ip和port不写,而使用默认的呀
//具体可在JedisPool处按住Ctrl并点击查看JedisPool查看源码呀...
JedisPool jedisPool = new JedisPool("192.168.0.110",6379);
Jedis jedis = jedisPool.getResource();
jedis.set("hello","world");
System.out.println(jedis.get("hello"));
}
到这里,Jedis,JedisPool是啥就说明白啦,但是大家很快就会发现,怎么jedis.set(key,value)的value只能是字符串呢???我要是需要把其它类型作为value怎么办啊???
可见value为123时,它已经报错了…
这个时候就需要看一下源码啦
public String set(String key, String value) {
this.checkIsInMultiOrPipeline();
this.client.set(key, value);
return this.client.getStatusCodeReply();
}
可以看到,value的类型为String,可能有小伙伴会认为123转为String也挺好转的啊,用String.valueOf(123)不就好了???可是如果我的value是一个对象怎么办呢??
嘿嘿,为了避免本篇文章篇幅过长,解决办法可以看这篇一款简单好用的序列化工具介绍
通俗点说…为了让Spring框架体系能够更加方便的接入Redis的功能,RedisTemplate其实就是Spring框架对Jedis的封装…是 spring-data-redis中使用redis的模版
那么如何对它进行使用呢???
org.springframework.boot
spring-boot-starter-data-redis
redis:
host: 192.168.0.110
port: 6379
@Resource
private RedisTemplate> redisTemplate;
//存数据 key为123456,value为map 类型为Map
redisTemplate.opsForValue().set("123456",map);
//以123456为key取数据
redisTemplate.opsForValue().get("123456");
到这里,大家有没有发现这次value为map,竟然没有报错呢?
这是因为RedisTemplate使用了JdkSerializationRedisSerializer,在存入数据时会将数据先序列化成字节数组然后再存入Redis数据库
可以看到红色箭头处的key:123456已经被序列化成字节数组了,可能会出现的问题就是用exists判断这个key是否存在时,显示不存在,但是在使用redisTemplate.opsForValue().get(“123456”)语句获取map时,返回的还是一个map,而不是字节化数组。也就是说,我们在存储数据时并不需要担心序列化的问题,redisTemplate自动进行序列化和反序列化。那么当我们存的key和value都为String类型的时候,我们想要在redis里直观地看到它们的值,应该怎么办呢?这个时候用StringRedisTemplate就比较方便啦,大家可能已经猜出了他们的关系…
首先我们可以来看看StringRedisTemplate和RedisTemplate之间的关系,还是贴源码:
public class StringRedisTemplate extends RedisTemplate {
public StringRedisTemplate() {
this.setKeySerializer(RedisSerializer.string());
this.setValueSerializer(RedisSerializer.string());
this.setHashKeySerializer(RedisSerializer.string());
this.setHashValueSerializer(RedisSerializer.string());
}
//此处省略...
}
可以看到StringRedisTemplate继承于RedisTemplate,且重新设置了序列化方式,方式为StringRedisSerializer
毫无疑问,StringRedisTemplate的使用方式和RedisTemplate是一样的,且上图蓝色箭头处就是利用StringRedisTemplate存起来的数据。
到这里,这四者的关系和使用就说完啦,大家觉得有没有说明白的地方欢迎评论区提出来,觉得不错不妨点个赞~