SpringBoot集成Redis
Redis简介:是一个开源的、使用 C 语言编写的、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库
主要特点
- 速度快,Redis 将数据存储在内存中,因此读写速度非常快,可以达到每秒数万次甚至更高的读写操作。这使得它非常适合处理高并发的场景,如缓存、实时排行榜等。
- 数据类型丰富,Redis 支持多种数据类型,包括字符串(strings)、哈希表(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。这使得开发者可以根据不同的应用场景选择合适的数据类型来存储和操作数据。
- 持久化,Redis 支持两种持久化方式:RDB(Redis Database)和 AOF(Append Only File)。RDB 是通过创建数据的快照来实现持久化,而 AOF 则是通过记录所有的写操作命令来实现持久化。这样可以保证在服务器重启或者出现故障时,数据不会丢失。
- 支持主从复制,Redis 可以配置为主从模式,实现数据的备份和高可用性。主节点负责写操作,从节点负责读操作,并从主节点同步数据。当主节点出现故障时,从节点可以自动切换为主节点,继续提供服务。
- 支持事务,Redis 支持事务操作,可以保证一组命令的原子性、一致性、隔离性和持久性。这使得开发者可以在 Redis 中执行复杂的操作,而不用担心数据的一致性问题。
SpringBoot操作Redis:
1添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>
2application.properties配置相关信息
spring.application.name=SpringBoot-redis
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.data.redis.database=0
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.password=123456
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0
从配置也可以看出来SpringBoot默认支持Lettuce连接池
3测试使用
package com.ktjiaoyu.crm;import com.ktjiaoyu.crm.pojo.User;
import com.ktjiaoyu.crm.service.UserService;
import jakarta.annotation.Resource;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;import java.util.concurrent.TimeUnit;
@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisTemlateTester {@Resourceprivate UserService userService;@Resourceprivate StringRedisTemplate stringRedisTemplate;//操作字符串数据@Resourceprivate RedisTemplate redisTemplate;//操作对象数据//操作字符串:@Testpublic void testString(){stringRedisTemplate.opsForValue().set("name","czkt");Assert.assertEquals("czkt",stringRedisTemplate.opsForValue().get("name"));}//操作实体:@Testpublic void testObj(){User user=new User("czkt","123456",null,null);ValueOperations<String,User> operations = redisTemplate.opsForValue();operations.set("ktjiaoyu.crm.user.czkt",user);User u = operations.get("ktjiaoyu.crm.user.czkt");System.out.println("user.usrName:"+u.getUsrName());}//超时失效@Testpublic void testExpire() throws InterruptedException{User user=new User("czkt","123456",null,null);ValueOperations<String,User> operations = redisTemplate.opsForValue();operations.set("expire",user,100, TimeUnit.MILLISECONDS);Thread.sleep(1000);boolean exists = redisTemplate.hasKey("expire");if(exists){System.out.println("exists is true");}else{System.out.println("exists is false");}}//操作哈稀@Testpublic void testHash(){HashOperations<String,Object,Object> hash=redisTemplate.opsForHash();hash.put("hash","name","ktjiaoyu");String value = (String) hash.get("hash","name");System.out.println("hash name value:"+value);}@Testpublic void testList(){ListOperations<String,String> list=redisTemplate.opsForList();list.leftPush("list","accp");list.leftPush("list","bdqn");list.leftPush("list","czkt");String value =list.rightPop("list");System.out.println("list value:"+value.toString());}@Testpublic void testGetUser(){User user=userService.getUser(2L);System.out.println("user:"+user.toString());}
}
SpringBoot集成Redis使用Cache缓存:
我们可以新创建一个RedisConfig配置类
package com.ktjiaoyu.crm.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
import java.time.Duration;
public class RedisConfig extends CachingConfigurerSupport {/*** 自定义生成key的规则* @return*/@Beanpublic KeyGenerator keyGenerator() {return new KeyGenerator() {@Overridepublic Object generate(Object target, Method method, Object... params) {//格式化缓存key字符串StringBuilder sb = new StringBuilder();//追加类名sb.append(target.getClass().getName());//追加方法名sb.append(method.getName());//遍历参数并且追加for (Object obj : params) {sb.append(obj.toString());}return sb.toString();}};}@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 正确的泛型类型RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper objectMapper = new ObjectMapper();// 设置对象的所有属性都是可访问的objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 开启对象的默认类型识别,避免反序列化时出现类型丢失objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);// jackson2JsonRedisSerializer.setObjectMapper(objectMapper);// 设置value的序列化方式和反序列化方式redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// 设置key的序列化方式,这里使用StringRedisSerializerredisTemplate.setKeySerializer(new StringRedisSerializer());// 如果使用hash结构存储,也需要设置hashKey和hashValue的序列化方式redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// 初始化模板redisTemplate.afterPropertiesSet();return redisTemplate;}/**** 采用RedisCachManager作为缓存管理器* @param factory* @return*/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory){//创建Redis序列化对象RedisSerializer<String> redisSerializer=new StringRedisSerializer();//创建Jackson对象Jackson2JsonRedisSerializer jackson2JsonRedisSerializer=new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om=new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);RedisCacheConfiguration config=RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(7)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager=RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}
}
总结:
Redis 在项目中的优势
- 高性能:Redis 是一种内存数据库,具有极快的读写速度,可以大大提高系统的响应性能。
- 数据结构丰富:支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,可以满足不同场景的需求。
- 持久化:可以将内存中的数据持久化到硬盘上,保证数据的安全性。
- 高可用:支持主从复制和哨兵模式,可以实现高可用性,避免单点故障。
常见的 Redis 操作
-
字符串操作:
设置字符串值:redisTemplate.opsForValue().set(key, value)
。获取字符串值:redisTemplate.opsForValue().get(key)
。 -
哈希表操作:
设置哈希表的值:redisTemplate.opsForHash().put(key, field, value)
。获取哈希表的值:redisTemplate.opsForHash().get(key, field)
。 -
列表操作:
向列表左侧插入元素:redisTemplate.opsForList().leftPush(key, value)
。从列表右侧弹出元素:redisTemplate.opsForList().rightPop(key)
。 -
集合操作:
向集合中添加元素:redisTemplate.opsForSet().add(key, value)
。获取集合中的所有元素:redisTemplate.opsForSet().members(key)
。 -
有序集合操作:
向有序集合中添加元素:redisTemplate.opsForZSet().add(key, value, score)
。获取有序集合中指定范围内的元素:redisTemplate.opsForZSet().rangeByScore(key, minScore, maxScore)
。