该栏目会系统的介绍 Redis 的知识体系,共分为相关概念、操作指令、主从复制等模块
文章目录
SpringBoot 整合 Redis
1、导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、配置文件
spring:
redis:
host: 127.0.0.1 # 服务器地址
port: 6379 # 服务器连接端口
database: 0 # 数据库索引号
timeout: 1800000 # 连接超时时间(毫秒)
lettuce:
pool:
max-active: 20 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 最大阻塞等待时间(负数表示没限制)
max-idle: 5 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
3、配置类
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
private RedisTemplate redisTemplate;
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer(Object.class);
// 解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext
.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext
.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
@Bean
@Order
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
// key序列化方式
template.setKeySerializer(redisSerializer);
// value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
// value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
this.redisTemplate = template;
return template;
}
/**
* 对hash类型的数据操作
*/
@Bean
public HashOperations<String, String, Object> hashOperations() {
return redisTemplate.opsForHash();
}
@Bean
public HashOperations<String, Integer, Object> hashIntegerOperations() {
return redisTemplate.opsForHash();
}
/**
* 对redis字符串类型数据操作
*/
@Bean
public ValueOperations<String, Object> valueOperations() {
return redisTemplate.opsForValue();
}
/**
* 对链表类型的数据操作
*/
@Bean
public ListOperations<String, Object> listOperations() {
return redisTemplate.opsForList();
}
/**
* 对无序集合类型的数据操作
*/
@Bean
public SetOperations<String, Object> setOperations() {
return redisTemplate.opsForSet();
}
/**
* 对有序集合类型的数据操作
*/
@Bean
public ZSetOperations<String, Object> zSetOperations() {
return redisTemplate.opsForZSet();
}
}
API 测试
1、字符串相关 API
@SpringBootTest(classes = SpringRedisDemoApplication.class)
class StringOperationTest {
@Autowired
private ValueOperations<String, Object> stringOps;
/**
* 对字符串类型进行操作
*/
@Test
void stringOps() {
// 保存单个值
stringOps.set("k1", "v1");
// 追加
stringOps.append("k1", "v11");
// 设置多个值
Map<String, Object> maps = new HashMap<>();
maps.put("k2", "v2");
maps.put("k3", 4);
stringOps.multiSet(maps);
// 增量
final Long value = stringOps.increment("k3");
System.out.println("增加后的值:" + value);
// 获取单个值
final Object v1 = stringOps.get("k1");
System.out.println("获取的值:" + v1);
// 获取多个值
List<String> keys = new ArrayList<>();
keys.add("k1");
keys.add("k2");
final List<Object> values = stringOps.multiGet(keys);
if (values != null) {
values.forEach(System.out::println);
}
}
}
2、列表相关 API
@SpringBootTest(classes = SpringRedisDemoApplication.class)
class ListOperationTest {
@Autowired
private ListOperations<String, Object> listOps;
/**
* 操作List列表
*/
@Test
public void listOps() {
// 存储单个元素
listOps.leftPush("scores", "89");
// 存储多个元素
List<Object> values = new ArrayList<>();
values.add("100");
values.add("89");
listOps.leftPushAll("scores", values);
// 修改元素
listOps.set("scores", 1, "99");
// 删除元素
final Long result = listOps.remove("scores", 1, "80");
System.out.println("删除个数:" + result);
// 获取元素个数
final Long size = listOps.size("scores");
System.out.println("元素个数:" + size);
// 获取单个元素
final Object value = listOps.leftPop("scores");
System.out.println("获取元素值:" + value);
}
}
3、集合相关 API
@SpringBootTest(classes = SpringRedisDemoApplication.class)
class SetOperationTest {
@Autowired
private SetOperations<String, Object> setOps;
/**
* 操作set集合
*/
@Test
public void setOps() {
// 添加单个元素
setOps.add("idCards", "001");
setOps.add("idCards", "002");
setOps.add("idCards", "003");
setOps.add("idCards", "004");
// 元素弹出
final List<Object> idCards = setOps.pop("idCards", 1);
if (idCards != null) {
idCards.forEach(System.out::println);
}
// 删除元素
final Long result = setOps.remove("idCards", "001");
System.out.println("删除结果:" + result);
// 判断集合是否包含元素
final Boolean flag = setOps.isMember("idCards", "003");
System.out.println("集合中是否有该元素:" + flag);
// 获取整个集合
final Set<Object> idCards2 = setOps.members("idCards");
if (idCards2 != null) {
idCards2.forEach(System.out::println);
}
}
}
4、有序集合相关 API
@SpringBootTest(classes = SpringRedisDemoApplication.class)
class ZSetOperationTest {
@Autowired
private ZSetOperations<String, Object> zsetOps;
/**
* 操作zset集合
*/
@Test
public void zsetOps() {
final String KEY = "students";
// 添加元素
zsetOps.add(KEY, "ZhangSan", 85);
zsetOps.add(KEY, "LiSi", 70);
zsetOps.add(KEY, "John", 75);
zsetOps.add(KEY, "Near", 96);
zsetOps.add(KEY, "Kiki", 96);
// 删除元素
final Long result = zsetOps.remove(KEY, "Kiki");
System.out.println("删除结果:" + result);
// 修改元素分数
final Double updateScore = zsetOps.incrementScore(KEY, "Near", 100);
System.out.println("修改后的分数:" + updateScore);
// 获取元素分数
final Double score = zsetOps.score(KEY, "John");
System.out.println("元素分数:" + score);
// 获取集合中元素个数
final Long count = zsetOps.count(KEY, 0, 100);
System.out.println("集合中元素个数:" + count);
// 获取所有元素
final Set<Object> members = zsetOps.range(KEY, 0, -1);
if (members != null) {
members.forEach(System.out::println);
}
System.out.println("=============================");
// 根据分数区间获取元素
final Set<ZSetOperations.TypedTuple<Object>> members2 =
zsetOps.rangeByScoreWithScores(KEY, 0, 100);
if (members2 != null) {
members2.forEach(member ->
System.out.println(member.getScore() + "==" + member.getValue()));
}
}
}
5、哈希表相关 API
@SpringBootTest(classes = SpringRedisDemoApplication.class)
class HashOperationTest {
@Autowired
private HashOperations<String, String, Object> hashOps;
/**
* 操作Hash类型
*/
@Test
public void hashOps() {
final String KEY = "user";
// 添加元素
hashOps.put(KEY, "name", "Near");
// 添加多个元素
Map<String, Object> maps = new HashMap<>();
maps.put("age", 18);
maps.put("address", "sz");
maps.put("getder", true);
hashOps.putAll(KEY, maps);
// 删除元素
final Long result = hashOps.delete(KEY, "gender");
System.out.println("删除结果:" + result);
// 获取单个元素
final Object name = hashOps.get(KEY, "name");
System.out.println("获取结果:" + name);
// 获取多个元素
List<String> keys = Arrays.asList("age", "address");
final List<Object> values = hashOps.multiGet(KEY, keys);
values.forEach(System.out::println);
System.out.println("===================");
// 获取所有元素
final Map<String, Object> student = hashOps.entries(KEY);
final Set<Map.Entry<String, Object>> entries = student.entrySet();
entries.forEach(entry -> System.out.println(
entry.getKey() + "====" + entry.getValue()));
}
}
6、发布订阅
接受类
@Slf4j
public class Receiver {
private AtomicInteger counter = new AtomicInteger();
public void receiveMessage(String message) {
log.info("Received <" + message + ">");
counter.incrementAndGet();
}
public int getCount() {
return counter.get();
}
}
订阅消息
// 配置订阅消息相关的对象
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public Receiver receiver() {
return new Receiver();
}
@Bean
public MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container =new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
// 订阅指定频道使用ChannelTopic,订阅模式使用PatternTopic
container.addMessageListener(listenerAdapter, new ChannelTopic("news"));
return container;
}
}
发布消息
@SpringBootTest(classes = SpringRedisDemoApplication.class)
class PublishOperationTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 发布消息
*/
@Test
public void publishTest() {
redisTemplate.convertAndSend("chan1", "Look at things!!");
}
}