SSM中操作Redis—Jedis
SSM中操作Redis——Jedis
1、Jedis
- jedis是基于java的redis客户端,集成了redis的命令操作,提供了连接池管理
- jedis的方法就是redis的命令
2、导入依赖
<!--jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
3、简单使用
@Test
public void quickTest() throws Exception {
// 参数一:redis服务器ip
// 参数二:redis服务器的端口号
Jedis jedis = new Jedis("192.168.27.132", 6379);
String name = jedis.set("name", "zhangsan");
System.out.println("name = " + name);
String value = jedis.get("name");
System.out.println("value = " + value);
}
4、连接池使用
@Test
public void JedisPoolTestDemo() {
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
String host = "192.168.27.132";
int port = 6379;
int timeout = 5000;
//产生连接池对象
JedisPool jedisPool = new JedisPool(poolConfig, host, port, timeout);
Jedis jedis = jedisPool.getResource();
jedis.set("name","张三");
jedis.set("name1","张三1");
jedis.set("name2","张三2");
jedis.hset("person","name","李四");
jedis.hset("person","name1","李四1");
jedis.hset("person","name2","李四2");
System.out.println(jedis.get("name"));
System.out.println(jedis.get("name1"));
System.out.println(jedis.get("name2"));
Map<String, String> person = jedis.hgetAll("person");
System.out.println("person = " + person);
//关闭后归还到连接池
jedis.close();
}
5、工具类封装连接池
public class JedisPoolUtils {
private static JedisPool jedisPool = null;
private static final String HOST = "192.168.27.132";
private static final int PORT = 6379;
private static final int TIMEOUT = 3000;
static {
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
jedisPool = new JedisPool(poolConfig,HOST,PORT,TIMEOUT);
}
public static Jedis getResource() {
return jedisPool.getResource();
}
}
6、连接池工具类使用
Jedis jedis = JedisPoolUtils.getResource(); //在连接池中获取jedis连接对象
String name = jedis.get("name");
System.out.println("name = " + name);
jedis.close();//关闭并归还连接
7、Jedis保存一个对象
- 可以通过json保存
- 也可以通过字节存储
7.1 通过json存储
思路:将创建好的对象转成json格式字符串,存储到redis中
//创建对象
Device device = new Device();
device.setId(1);
device.setDeviceName("挖掘机");
device.setPrice(30000D);
//json转换
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(device);
//获取jedis对象
Jedis jedis = JedisPoolUtils.getResource();
//存储对象
jedis.set("device:" + device.getId(), json);
String deviceString = jedis.get("device:" + device.getId());
System.out.println("deviceString = " + deviceString);
//归还连接到连接池
jedis.close();
7.2 字节存储
思路:
-
将创建好的对象序列化为字节数组,存储到redis中
-
从redis中获取字节数组,并将字节数组反序列化为对象
//创建对象
Device device = new Device();
device.setId(1);
device.setDeviceName("挖掘机");
device.setPrice(30000D);
//获取jedis对象
Jedis jedis = JedisPoolUtils.getResource();
//对象转换为字节数组,使用SerializationUtils的serialize()方法
byte[] key = ("device:" + device.getId()).getBytes();
byte[] value = SerializationUtils.serialize(device);
//存储字节
jedis.set(key, value);
//获取key对应的value
byte[] bytes = jedis.get(key);
//SerializationUtils的deserialize()方法 将字节转为对象
Device device1 = (Device) SerializationUtils.deserialize(bytes);
System.out.println(device1);
//归还连接到连接池
jedis.close();
8、Jedis管道操作
当我们有10000条数据要存储到redis中,使用原始方式存:
@Test
public void tenThousandTest(){
Jedis jedis = JedisPoolUtils.getResource();
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
jedis.set("i:"+i,"v:"+i);
}
System.out.println(System.currentTimeMillis()-start);//大概4秒
jedis.close();
}
当执行完之后得到时间差,发现用时大概4秒。
为什么redis读写性能优异,却花费了4秒钟?
使用过查看redis性能命令的小伙伴会发现读写的性能能达到100000次/s
据官方的bench-mark数据:读的速度是110000次/s,写的速度是81000次/s
#redis写的性能
redis-benchmark set
#redis读的性能
redis-benchmark get
那为什么在这里执行10000次写却用了4秒钟,是不是redis性能不靠谱啊
其实不然,我们仔细想一下,我们的jedis程序和redis服务器是在不同服务器上,
那Jedis的数据要保存到redis中就要通过网络传输
对于上面代码而言,每写一个就要传一个到redis中,一共要发送10000次,这之间消耗的时间是比较久的,也就对代码执行完之后计算得出的时间产生了影响。
- 其实redis的读写性能是ok的,其瓶颈在于传输性能上。
那有什么提升jedis传输性能的方法呢
有,Jedis提供了一个pipelined(),也就是管道操作,我们来看升级后的代码
@Test
public void test(){
Jedis jedis = JedisPoolUtils.getResource();
Long start = System.currentTimeMillis();
Pipeline pipelined = jedis.pipelined();
for (int i = 0; i < 10000; i++) {
pipelined.set("k:"+i,"v:"+i);
}
System.out.println(System.currentTimeMillis()-start);//55毫秒
jedis.close();
}
最后测试发现执行几乎瞬间完成,用时55毫秒,比4秒提升了70多倍。
为什么管道操作那么快
它将所有操作都打包,一次性发给redis服务器,由原先一万次的传输变为一次传输,大大提高了传输性能,节省了时间。
而redis接收到之后做一万次写入,一万次写入对于redis来说小菜一碟。