Redis基本命令
控制台登录
redis-cli
命令提示符变成127.0.0.1:6379>
后,可以执行Redis的相关命令
-
set KEY VALUE
:存入数据,例如set username1 tom
,如果KEY不存在,则表示新增数据,如果KEY已经存在,则会覆盖原有的数据,所以,set
命令既是新增数据的命令,也是修改数据的命令 -
get KEY
:取出数据,例如get username1
,如果KEY存在,则返回对应的VALUE,如果KEY不存在,则返回(nil)
,相当于Java中的null
-
keys PATTERN
:根据模式(PATTERN
)获取KEY的列表,例如keys username1
,如果存在匹配模式的KEY,则返回这些KEY的集合,如果不存在,则返回(empty list or set)
,在使用模式时,可以使用*
作为通配符,例如keys username*
,将返回所有以username
作为前缀的KEY,甚至,你可以使用keys *
查询所有KEY- **注意:**在生产环境中,禁止使用此命令!
-
del KEY [KEY ...]
:根据若干个KEY(至少1个)删除数据,将返回受影响的数据量,例如执行delete age1
,当此KEY存在时,将返回(integer) 1
,当此KEY不存在时,将返回(integer) 0
-
flushdb
:清空当前数据库
Redis中的数据类型
Redis中的经典数据类型有5种,分别是:string(一般值,例如字符串、数值等可以直接字面表示的) / list / set / hash(对象,对应Java语句中的Map
) / zset
另外,还有:bitmap / hyperloglog / Geo / Stream
Redis中的list类型
在Redis中,list类型的数据使用的是先进后出、后进先出的栈结构:
在学习Redis时,应该把Redis中的栈结构水平旋转90度来理解!
在操作Redis中的list数据时,可以从左侧进行压栈或弹栈的操作,例如:
也可以从右侧进行压栈或弹栈的操作,例如:
当从Redis中读取list的数据时,始终从左至右读取数据,通常,为了符合绝大多数开发者的使用习惯,会采“从右侧压入数据”的做法。
在Redis的list中,每个数据都有2个下标值,分别是从左至右、从0开始顺序递增的下标,和从右至左、从-1开始顺序递减的下标,例如:
注意:在获取list的数据区间时,必须保证start在end的左侧!
Redis编程
在基于Spring Boot的项目中,实现Redis编程需要添加spring-boot-starter-data-redis
依赖项。
然后,需要使用RedisTemplate
工具类的API实现Redis编程,通常会在配置类中使用@Bean
方法来配置RedisTemplate
,则后续可以在任何组件类中自动装配RedisTemplate
,然后调用相关访问来访问数据。
添加Redis依赖
<!-- Spring Boot支持Redis编程的依赖项 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot.version}</version>
</dependency>
Redis配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import java.io.Serializable;
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Serializable> redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(RedisSerializer.json());
return redisTemplate;
}
}
import cn.tedu.tmall.admin.mall.pojo.entity.Category;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@SpringBootTest
public class RedisTests {
// 如果需要执行与值相关的数据访问,需要先通过RedisTemplate得到???Operations类型的对象
// 例如:操作字符串值时,需要先得到ValueOperation,操作List值时,需要得到ListOperations
// 如果需要执行的数据访问与值无关,直接调用RedisTemplate的API即可
@Autowired
RedisTemplate<String, Serializable> redisTemplate;
// 存入字符串类型的值
// 如果存入中文值,在终端窗口中,会显示为对应的十六进制值,但并不影响取出数据
@Test
void setValue() {
ValueOperations<String, Serializable> opsForValue = redisTemplate.opsForValue();
opsForValue.set("username", "张三");
System.out.println("向Redis中写入数据,完成!");
}
// 取出字符串类型的值
@Test
void getValue() {
ValueOperations<String, Serializable> opsForValue = redisTemplate.opsForValue();
Serializable value = opsForValue.get("username");
System.out.println("向Redis中取出数据:" + value);
}
// 存入自定义类型的值,与存入字符串完全相同
@Test
void setObjectValue() {
Category category = new Category();
category.setId(95L);
category.setName("Computer");
ValueOperations<String, Serializable> opsForValue = redisTemplate.opsForValue();
opsForValue.set("category", category);
System.out.println("向Redis中写入自定义类型的数据,完成!");
}
// 取出自定义类型的值,与取出字符串完全相同
@Test
void getObjectValue() {
ValueOperations<String, Serializable> opsForValue = redisTemplate.opsForValue();
Serializable value = opsForValue.get("category");
System.out.println("向Redis中取出数据:" + value);
}
// 使用keys命令获取所有Key
@Test
void keys() {
String pattern = "*"; // keys *
Set<String> keys = redisTemplate.keys(pattern);
System.out.println("当前Redis中所有的Key:" + keys);
}
// 根据Key删除数据
@Test
void delete() {
String key = "username";
Boolean deleteResult = redisTemplate.delete(key);
System.out.println("删除数据完成,结果:" + deleteResult);
}
// 根据若干个Key批量删除数据
@Test
void deleteBatch() {
Set<String> keys = new HashSet<>();
keys.add("username1");
keys.add("username3");
keys.add("username5");
Long deleteCount = redisTemplate.delete(keys);
System.out.println("删除数据完成,成功删除的数据量:" + deleteCount);
}
// 向Redis中存入list数据
@Test
void rightPush() {
List<Category> categoryList = new ArrayList<>();
for (int i = 1; i <= 8; i++) {
Category category = new Category();
category.setId(i + 0L);
category.setName("测试类别" + i);
categoryList.add(category);
}
ListOperations<String, Serializable> opsForList = redisTemplate.opsForList();
String key = "categoryList";
for (Category category : categoryList) {
opsForList.rightPush(key, category);
}
System.out.println("向Redis中写入list数据,完成!");
}
// 获取list的长度
@Test
void listSize() {
String key = "categoryList";
ListOperations<String, Serializable> opsForList = redisTemplate.opsForList();
Long size = opsForList.size(key);
System.out.println("Redis中Key=" + key + "的list数据的长度为:" + size);
}
// 读取list的区间
@Test
void listRange() {
String key = "categoryList";
long start = 0;
long end = -1;
ListOperations<String, Serializable> opsForList = redisTemplate.opsForList();
List<Serializable> list = opsForList.range(key, start, end);
for (Serializable serializable : list) {
System.out.println(serializable);
}
}
}