文章目录
- 一、Redis环境
- 1、环境:CentOS7.0,redis-4.0.2
- 2、首先启动redis服务
- 二、Redis数据结构
- 1、string(字符串)
- (1)键值对
- (2)使用mset和mget批量操作
- (3)过期时间设置和set扩展
- (4)计数
- 2、list (列表)
- (1)队列,左进右出,先进先出
- (2)栈,左进左出,先进后出
- (3)慢操作
- 3、hash(字典)
- 4、set(集合)
- zset(有序集合)
- 三、SpringBoot项目中使用redisTemplate操作Redis
- 1、工具代码如下
- 2、其中用到的序列化工具类如下
一、Redis环境
1、环境:CentOS7.0,redis-4.0.2
2、首先启动redis服务
[root@songsir03 redis]# cd redis-4.0.2/src/
[root@songsir03 src]# ./redis-server
然后启动客户端可执行命令操作:(上个窗口保证没有关闭的情况下,新开一个窗口,
进入redis的src下执行redis-cli) (redis服务窗口默认情况下在关闭时会关闭服务)
[root@songsir03 src]# ./redis-cli
二、Redis数据结构
Redis有五种数据结构,分别为string (字符串)、list (列表)、
set(集合)、hash(哈希) 和 zset(有序集合)。
1、string(字符串)
(1)键值对
127.0.0.1:6379> set name songsir
OK
127.0.0.1:6379> get name
"songsir"
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> exists name
(integer) 0
(2)使用mset和mget批量操作
127.0.0.1:6379> mset name1 songsir1 name2 songsir2
OK
127.0.0.1:6379> mget name1 name2
1) "songsir1"
2) "songsir2"
127.0.0.1:6379>
(3)过期时间设置和set扩展
127.0.0.1:6379> set name songsir
OK
127.0.0.1:6379> get name
"songsir"
127.0.0.1:6379> expire name 6 # 6s后过期
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> setex name 5 songsir
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> setex name 5 songsir
OK
127.0.0.1:6379> get name
"songsir"
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379>
127.0.0.1:6379> setnx name songsir # 如果name不存在,则执行set操作
(integer) 1
127.0.0.1:6379> get name
"songsir"
127.0.0.1:6379> setnx name songsir2
(integer) 0 # name存在,新的set不成功
127.0.0.1:6379> get name
"songsir"
(4)计数
如果value是整数,可以自增自检操作,最大值 = 9223372036854775807,超过这个数报错
127.0.0.1:6379> set song 22
OK
127.0.0.1:6379> incr song
(integer) 23
127.0.0.1:6379> incrby song 22
(integer) 45
127.0.0.1:6379> incrby song -22
(integer) 23
127.0.0.1:6379> set song 9223372036854775807
OK
127.0.0.1:6379> incr song
(error) ERR increment or decrement would overflow
2、list (列表)
Redis的列表类似(不是等同)Java的LinkedList,链表结构,插入和删除速度快,查询慢
(1)队列,左进右出,先进先出
127.0.0.1:6379> rpush books java c python
(integer) 3
127.0.0.1:6379> llen books
(integer) 3
127.0.0.1:6379> lpop books
"java"
127.0.0.1:6379> lpop books
"c"
127.0.0.1:6379> lpop books
"python"
127.0.0.1:6379> lpop books
(nil)
(2)栈,左进左出,先进后出
(栈相当于一个一端封闭的管子,数据一个个进去之后,压栈一个个弹出)
127.0.0.1:6379> rpush books java c python
(integer) 3
127.0.0.1:6379> rpop books
"python"
127.0.0.1:6379> rpop books
"c"
127.0.0.1:6379> rpop books
"java"
127.0.0.1:6379> rpop books
(nil)
(3)慢操作
lindex相当于java的get(),遍历链表,性能低;
ltrim截取 保留字段;其中参数index可以为负数,-1表示倒数第一个,-2表示倒数第二个。
127.0.0.1:6379> rpush books java c python
(integer) 3
127.0.0.1:6379> lindex books 1 # 获取下标为1
"c"
127.0.0.1:6379> lrange books 0 -1 # 遍历所有,慎用
1) "java"
2) "c"
3) "python"
127.0.0.1:6379> ltrim books 1 -1 # 截取下标为1到最后
OK
127.0.0.1:6379> lrange books 0 -1
1) "c"
2) "python"
3、hash(字典)
Redis的hash相当于Java的HashMap,数据结构和HashMap基本一样,
不过hash的value只能是字符串。
127.0.0.1:6379> hset books java "Java从入门到放弃"
(integer) 1
127.0.0.1:6379> hset books c "c从精通到入土"
(integer) 1
127.0.0.1:6379> hgetall books
1) "java"
2) "Java\xe4\xbb\x8e\xe5\x85\xa5\xe9\x97\xa8\xe5\x88\xb0\xe6\x94\xbe\xe5\xbc\x83"
3) "c"
4) "c\xe4\xbb\x8e\xe7\xb2\xbe\xe9\x80\x9a\xe5\x88\xb0\xe5\x85\xa5\xe5\x9c\x9f"
上面发现中文乱码了,只需要启动redis-cli时在后面加上–raw即可
[root@songsir03 src]# redis-cli --raw
127.0.0.1:6379> hgetall books
java
Java从入门到放弃
c
c从精通到入土
127.0.0.1:6379> hget books java
Java从入门到放弃
4、set(集合)
Redis的集合相当于Java的HashSet,无序唯一的。
127.0.0.1:6379> sadd books java
1
127.0.0.1:6379> sadd books java
0
127.0.0.1:6379> sadd books java c python
2
127.0.0.1:6379> smembers books # 无序
java
python
c
127.0.0.1:6379> spop books # 随机弹出一个(无序)
python
zset(有序集合)
下面zset值存储books的名称,score存储价格
127.0.0.1:6379> zadd books 9.0 "java 从入门到放弃"
1
127.0.0.1:6379> zadd books 9.1 "c"
1
127.0.0.1:6379> zadd books 9.9 "python"
1
127.0.0.1:6379> zrange books 0 -1
java 从入门到放弃
c
python
127.0.0.1:6379> zscore books "c" # 获取c的价格
9.0999999999999996 # score采用double存储,精度失真
127.0.0.1:6379> zrank books "c" # 获取c的次序
1
127.0.0.1:6379> zrank books "java 从入门到放弃"
0
三、SpringBoot项目中使用redisTemplate操作Redis
1、工具代码如下
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class SongsirRedisTemplate<E> {
@Autowired
private RedisTemplate redisTemplate;
// 序列化工具类
@Autowired
private SerializeUtil<E> serialize;
public static ListOperations<String, String> list;
/**
* 根据键值获取value
*/
public E get(String key) {
ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
return key == null ? null : serialize.unserialize(opsForValue.get(key));
}
/**
* 设置键值对(无超时时间)
* @param key
* @param value
* @return
*/
public boolean set(String key, E value) {
ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
try {
opsForValue.set(key, serialize.serialize(value));
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 设置键值对 (设置有效时间,以秒为单位)
* @param key
* @param value
* @param expire
* @return boolean
*/
public boolean set(String key, E value, long expire) {
ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
try {
opsForValue.set(key, serialize.serialize(value), expire, TimeUnit.SECONDS);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key删除键值对
* @param key
* @return
*/
public boolean delete(String key) {
try {
redisTemplate.delete(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* lpush 进队列
* @param key
* @param value
* @return
*/
public Long lpush(String key, String value) {
list = redisTemplate.opsForList();
try {
Long leftPush = list.leftPush(key, value);
return leftPush;
} catch (Exception e) {
e.printStackTrace();
return Long.valueOf(-1);
}
}
/**
* rpop 出队列
* @param key
* @return
*/
public String rpop(String key) {
list = redisTemplate.opsForList();
try {
return list.rightPop(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 返回指定队列(list)名队列长度
* @param key
* @return
*/
public Long llen(String key) {
list = redisTemplate.opsForList();
return list.size(key);
}
}
2、其中用到的序列化工具类如下
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
@Component
public class SerializeUtil<E> {
public String serialize(E object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
String str = baos.toString("ISO-8859-1");
return URLEncoder.encode(str, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
baos.close();
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
@SuppressWarnings("unchecked")
public E unserialize(String serializeStr) {
String readStr = "";
if(serializeStr == null || "".equals(serializeStr)) {
return null;
}
try {
readStr = URLDecoder.decode(serializeStr, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
ObjectInputStream ois = null;
InputStream bais = null;
try {
bais = new ByteArrayInputStream(readStr.getBytes("ISO-8859-1"));
ois = new ObjectInputStream(bais);
return (E) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ois.close();
bais.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}