当前位置: 首页 > 科技观察

SpringBoot中集成Redis(缓存篇)

时间:2023-03-12 01:59:48 科技观察

实际开发中需要缓存处理。我们不可能每次客户端请求服务器的时候都去请求服务器。服务器每次都必须搜索数据库。为什么要使用缓存?说到底就是为了提高系统的运行速度。将用户经常访问的内容存放在离用户最近、访问速度最快的地方,提高用户的响应速度。今天就来说说在springboot中集成redis的详细步骤。1、安装redis下载地址:https://redis.io/download首先在本地安装一个redis程序。安装过程非常简单(跳过)。安装完成后,进入redis文件夹,可以看到如下:点击redis-server.exe启动redis服务,如下图,表示redis服务启动成功:然后我们就可以启动用于测试的redis客户端:2.集成到springboot1中,在项目中添加redis依赖,在pom文件中添加:org.springframework.bootspring-boot-starter-data-redis2.在application.yml中添加redis配置:##默认密码为空redis:host:127.0.0.1#Redisserverconnectionportport:6379jedis:pool:#连接池最大连接数(使用负值表示不限制)max-active:100#连接池最小空闲连接数max-idle:10#连接池最大阻塞等待时间(使用负值表示不限制)max-wait:100000#Connectiontimeout(毫秒)timeout:5000#默认是index0database:03,新建RedisConfiguration配置类,继承CachingConfigurerSupport,@EnableCaching开启注解@Configuration@EnableCachingpublicclassRedisConfigurationextendsCachingConfigurerSupport{/***自定义生成key的规则*/@OverridepublicKeyGeneratorkeyGenerator(){returnnewmekeyGenerator(){@OverridepublicgenerateObject,MethodObject,Object...objects){//格式化缓存键字符串StringBuildersb=newStringBuilder();//追加类名sb.append(o.getClass().getName());//追加方法名sb.append(method.getName());//遍历参数并追加for(Objectobj:objects){sb.append(obj.toString());}System.out.println("调用Redis缓存Key:"+sb.toString());returnsb.toString();}};}/***使用RedisCacheManager作为存储管理器*@paramconnectionFactory*/@BeanpublicCacheManagercacheManager(RedisConnectionFactoryconnectionFactory){RedisCacheManagerredisCacheManager=RedisCacheManager.create(connectionFactory);returnredisCacheManager;}@BeanpublicRedisStringTemplate>{/***哈希结构添加元素*@paramkeykey*@paramhashKeyhashKey*@paramdomain元素*/voidhashPut(Stringkey,HKhashKey,Tdomain);/***哈希结构获取指定key所有键值对*@paramkey*@return*/MaphashFindAll(Stringkey);/***哈希结构获取单个元素*@paramkey*@paramhashKey*@return*/ThashGet(Stringkey,HKhashKey);voidhashRemove(Stringkey,HKhashKey);/***List结构在尾部添加元素(右)*@paramkey*@paramdomain*@return*/LonglistPush(Stringkey,Tdomain);/***List结构向头部添加元素(Left)添加元素*@paramkey*@paramdomain*@return*/LonglistUnshift(Stringkey,Tdomain);/***List结构获取所有元素*@paramkey*@return*/ListlistFindAll(Stringkey);/***去掉List结构,获取数组首元素*@paramkey*@return*/TlistLPop(Stringkey);/***实体类对象的*@paramkey*@paramdomain*@return*/voidvaluePut(Stringkey,Tdomain);/***获取对象实体类*@paramkey*@return*/TgetValue(Stringkey);voidremove(Stringkey);/***设置过期时间*@paramkeykey*@paramtimeouttime*@paramtimeUnittimeunit*/booleanexpirse(Stringkey,longtimeout,TimeUnittimeUnit);}下面是创建RedisHelperImpl接口的实现@Service("RedisHelper")publicclassRedisHelperImplimplementsRedisHelper{//在构造函数中获取redisTemplate实例,key(nothashKey)默认使用String类型privateRedisTemplateredisTemplate;//在构造函数中通过redisTemplate的工厂方法实例化操作对象privateHashOperationshashOperations;privateListOperationslistOperations;privateZSetOperationszSetOperations;privateSetOperationssetOperations;privateValueOperationsvalueOperations;//虽然IDEA报错,但是还是可以注入成功,实例化之后操作对象可以直接调用方法操作Redis数据库@AutowiredpublicRedisHelperImpl(RedisTemplateredisTemplate){this.redisTemplate=redisTemplate;this.hashOperations=redisTemplate.opsForHash();this.listOperations=redisTemplate.opsForList();this.zSetOperations=redisTemplate.opsForZSet();this.setOperations=redisTemplate.opsForSet();this.valueOperations=redisTemplate.opsForValue();}@OverridepublicvoidhashPut(Stringkey,HKhashKey,Tdomain){hashOperations.put(key,hashKey,domain);}@OverridepublicMaphashFindAll(Stringkey){returnhashOperations.entries(key);}@OverridepublicThashGet(Stringkey,HKhashKey){returnhashOperations.get(key,hashKey);}@OverridepublicvoidhashRemove(Stringkey,HKhashKey){hashOperations.delete(key,hashKey);}@OverridepublicLonglistPush(Stringkey,Tdomain){returnlistOperations.rightPush(key,domain);}@OverridepublicLonglistUnshift(Stringkey,Tdomain){returnlistOperations.leftPush(key,domain);}@OverridepublicListlistFindAll(Stringkey){if(!redisTemplate.hasKey(key)){returnnull;}returnlistOperations.range(key,0,listOperations.size(key));}@OverridepublicTlistLPop(Stringkey){returnlistOperations.leftPop(key);}@OverridepublicvoidvaluePut(Stringkey,Tdomain){valueOperations.set(key,domain);}@OverridepublicTgetValue(Stringkey){returnvalueOperations.get(key);}@Overridepublicvoidremove(Stringkey){redisTemplate.delete(key);}@Overridepublicbooleanexpirse(Stringkey,longtimeout,TimeUnittimeUnit){returnredisTemplate.expire(key,timeout,timeUnit);}}三、测试编写TestRedis类用于测试@RunWith(SpringRunner.class)@SpringBootTestpublicclassTestRedis{@AutowiredprivateStringRedisTemplatestringRedisTemplate;@AutowiredprivateRedisTemplatedis;AutowiredprivateRedisHelperImplredisHelper;@Testpublicvoidtest()throwsException{//基础写法//stringRedisTemplate.opsForValue().set("aaa","111");//Assert.assertEquals("111",stringRedisTemplate.opsForValue().get("aaa"));//System.out.println(stringRedisTemplate.opsForValue().get("aaa"));Authoruser=newAuthor();user.setName("Alex");user.setIntro_l("不会输入篮球节目不是好人");redis他lper.valuePut("aaa",user);System.out.println(redisHelper.getValue("aaa"));}@TestpublicvoidtestObj()throwsException{Authoruser=newAuthor();user.setName("Jerry");user.setIntro_l("不会打篮球的程序不是好人!");ValueOperationsoperations=redisTemplate.opsForValue();operations.set("502",user);Thread.sleep(500);booleanexists=redisTemplate.hasKey("502");if(exists){System.out.println(redisTemplate.opsForValue().get("502"));}else{System.out.println("existssisfalse");}//Assert.assertEquals("aa",operations.get("com.neo.f").getUserName());}}运行TestRedis测试类,结果如下:注意:如果redisTemplate在RedisConfiguration(RedisConnectionFactoryfactory)注解中没有配置,会造成key和value的序列化问题,有兴趣的可以试试序列化:序列化框架的选择与比较四、项目实战首先需要在程序入口的Application中添加@EnableCaching注解启用缓存@EnableCaching//启用缓存@SpringBootApplicationpublicclassPoetryApplication{publicstaticvoidmain(String[]args){SpringApplication.run(PoetryApplication.class,args);}}上面redis相关的写法是我们自定义设置获取的,所以我们经常使用redis在访问接口缓存相关的实体对象和集合,那么如何做我们意识到了吗?比如我现在想把作者相关信息的缓存数据缓存到AuthorController中,怎么办?如下:@RestController@RequestMapping(value="/poem")publicclassAuthorController{privatefinalstaticLoggerlogger=LoggerFactory.getLogger(AuthorController.class);@AutowiredprivateAuthorRepositoryauthorRepository;@Cacheable(value="poemInfo")//根据方法自动生成缓存@PostMapping(value="/poemInfo")publicResultauthor(@RequestParam("author_id")intauthor_id,@RequestParam("author_name")Stringauthor_name){if(StringUtils.isEmpty(author_id)||StringUtils.isEmpty(author_name)){returnResultUtils.error(ResultCode.INVALID_PARAM_EMPTY);}作者作者;可选<作者>可选=authorRepository.getAuthorByIdAndName(author_id,author_name);if(optional.isPresent()){author=optional.get();//通过\n或多个空格过滤去重if(!StringUtils.isEmpty(author.getIntro_l())){Strings=author.getIntro_l();Stringintro=s.split("\\s+")[0];author.setIntro_l(intro);}}else{returnResultUtils.error(ResultCode.NO_FIND_THINGS);}returnResultUtils.ok(author);}}这里@Cacheable(value="poemInfo")注解的意思是根据方法自动生成缓存,value为缓存的key。这里我们已经将redis集成到springboot中了。