0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Springboot+redis操作多种实现

Android编程精选 来源:CSDN技术社区 作者:Tonels 2021-09-22 10:48 次阅读

一、Jedis,Redisson,Lettuce三者的区别共同点:都提供了基于Redis操作的Java API,只是封装程度,具体实现稍有不同。

不同点:

1.1、Jedis

是Redis的Java实现的客户端。支持基本的数据类型如:String、Hash、List、Set、Sorted Set。

特点:使用阻塞的I/O,方法调用同步,程序流需要等到socket处理完I/O才能执行,不支持异步操作。Jedis客户端实例不是线程安全的,需要通过连接池来使用Jedis。

1.2、Redisson

优点点:分布式锁,分布式集合,可通过Redis支持延迟队列。

1.3、 Lettuce

用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器

基于Netty框架的事件驱动的通信层,其方法调用是异步的。Lettuce的API是线程安全的,所以可以操作单个Lettuce连接来完成各种操作。

二、RedisTemplate2.1、使用配置

maven配置引入,(要加上版本号,我这里是因为Parent已声明)


	

<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-data-redisartifactId> dependency>

application-dev.yml


	

spring: redis: host:192.168.1.140 port:6379 password: database:15#指定redis的分库(共16个0到15)

2.2、使用示例


	

@Resource privateStringRedisTemplatestringRedisTemplate; @Override publicCustomersEntityfindById(Integerid){ //需要缓存 //所有涉及的缓存都需要删除,或者更新 try{ StringtoString=stringRedisTemplate.opsForHash().get(REDIS_CUSTOMERS_ONE,id+"").toString(); if(toString!=null){ returnJSONUtil.toBean(toString,CustomersEntity.class); } }catch(Exceptione){ e.printStackTrace(); } //缓存为空的时候,先查,然后缓存redis OptionalbyId=customerRepo.findById(id); if(byId.isPresent()){ CustomersEntitycustomersEntity=byId.get(); try{ stringRedisTemplate.opsForHash().put(REDIS_CUSTOMERS_ONE,id+"",JSONUtil.toJsonStr(customersEntity)); }catch(Exceptione){ e.printStackTrace(); } returncustomersEntity; } returnnull; }

2.3、扩展

2.3.1、spring-boot-starter-data-redis的依赖包

3.3.2、stringRedisTemplate API(部分展示)

opsForHash --》 hash操作

opsForList --》 list操作

opsForSet --》 set操作

opsForValue --》 string操作

opsForZSet --》 Zset操作

3.3.3 StringRedisTemplate默认序列化机制


	

publicclassStringRedisTemplateextendsRedisTemplate<String,String>{ /** *ConstructsanewStringRedisTemplateinstance.{@link#setConnectionFactory(RedisConnectionFactory)} *and{@link#afterPropertiesSet()}stillneedtobecalled. */ publicStringRedisTemplate(){ RedisSerializerstringSerializer=newStringRedisSerializer(); setKeySerializer(stringSerializer); setValueSerializer(stringSerializer); setHashKeySerializer(stringSerializer); setHashValueSerializer(stringSerializer); } }

三、RedissonClient 操作示例

3.1 基本配置

3.1.1、Maven pom 引入

	

<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-data-redisartifactId> dependency> <dependency> <groupId>org.redissongroupId> <artifactId>redissonartifactId> <version>3.8.2version> <optional>trueoptional> dependency> <dependency> <groupId>org.redissongroupId> <artifactId>redisson-spring-boot-starterartifactId> <version>LATESTversion> dependency>

3.1.2、添加配置文件Yaml或者json格式

redisson-config.yml


	

#Redisson配置 singleServerConfig: address:"redis://192.168.1.140:6379" password:null clientName:null database:15#选择使用哪个数据库0~15 idleConnectionTimeout:10000 pingTimeout:1000 connectTimeout:10000 timeout:3000 retryAttempts:3 retryInterval:1500 reconnectionTimeout:3000 failedAttempts:3 subscriptionsPerConnection:5 subscriptionConnectionMinimumIdleSize:1 subscriptionConnectionPoolSize:50 connectionMinimumIdleSize:32 connectionPoolSize:64 dnsMonitoringInterval:5000 #dnsMonitoring:false threads:0 nettyThreads:0 codec: class:"org.redisson.codec.JsonJacksonCodec" transportMode:"NIO"

或者,配置 redisson-config.json


	

{ "singleServerConfig":{ "idleConnectionTimeout":10000, "pingTimeout":1000, "connectTimeout":10000, "timeout":3000, "retryAttempts":3, "retryInterval":1500, "reconnectionTimeout":3000, "failedAttempts":3, "password":null, "subscriptionsPerConnection":5, "clientName":null, "address":"redis://192.168.1.140:6379", "subscriptionConnectionMinimumIdleSize":1, "subscriptionConnectionPoolSize":50, "connectionMinimumIdleSize":10, "connectionPoolSize":64, "database":0, "dnsMonitoring":false, "dnsMonitoringInterval":5000 }, "threads":0, "nettyThreads":0, "codec":null, "useLinuxNativeEpoll":false }

3.1.3、读取配置

新建读取配置类


	

@Configuration publicclassRedissonConfig{ @Bean publicRedissonClientredisson()throwsIOException{ //两种读取方式,Config.fromYAML和Config.fromJSON //Configconfig=Config.fromJSON(RedissonConfig.class.getClassLoader().getResource("redisson-config.json")); Configconfig=Config.fromYAML(RedissonConfig.class.getClassLoader().getResource("redisson-config.yml")); returnRedisson.create(config); } }

或者,在 application.yml中配置如下


	

spring: redis: redisson: config:classpath:redisson-config.yaml

3.2 使用示例


	

@RestController @RequestMapping("/") publicclassTeController{ @Autowired privateRedissonClientredissonClient; staticlongi=20; staticlongsum=300; //==========================String======================= @GetMapping("/set/{key}") publicStrings1(@PathVariableStringkey){ //设置字符串 RBucketkeyObj=redissonClient.getBucket(key); keyObj.set(key+"1-v1"); returnkey; } @GetMapping("/get/{key}") publicStringg1(@PathVariableStringkey){ //设置字符串 RBucketkeyObj=redissonClient.getBucket(key); Strings=keyObj.get(); returns; } //==========================hash=======================-= @GetMapping("/hset/{key}") publicStringh1(@PathVariableStringkey){ Urur=newUr(); ur.setId(MathUtil.randomLong(1,20)); ur.setName(key); //存放Hash RMapss=redissonClient.getMap("UR"); ss.put(ur.getId().toString(),ur); returnur.toString(); } @GetMapping("/hget/{id}") publicStringh2(@PathVariableStringid){ //hash查询 RMapss=redissonClient.getMap("UR"); Urur=ss.get(id); returnur.toString(); } //查询所有的keys @GetMapping("/all") publicStringall(){ RKeyskeys=redissonClient.getKeys(); Iterablekeys1=keys.getKeys(); keys1.forEach(System.out::println); returnkeys.toString(); } //================================读写锁测试============================= @GetMapping("/rw/set/{key}") publicvoidrw_set(){ //RedissonLock. RBucketls_count=redissonClient.getBucket("LS_COUNT"); ls_count.set("300",360000000l,TimeUnit.SECONDS); } //减法运算 @GetMapping("/jf") publicvoidjf(){ Stringkey="S_COUNT"; //RAtomicLongatomicLong=redissonClient.getAtomicLong(key); //atomicLong.set(sum); //longl=atomicLong.decrementAndGet(); //System.out.println(l); RAtomicLongatomicLong=redissonClient.getAtomicLong(key); if(!atomicLong.isExists()){ atomicLong.set(300l); } while(i==0){ if(atomicLong.get()>0){ longl=atomicLong.getAndDecrement(); try{ Thread.sleep(1000l); }catch(InterruptedExceptione){ e.printStackTrace(); } i--; System.out.println(Thread.currentThread().getName()+"->"+i+"->"+l); } } } @GetMapping("/rw/get") publicStringrw_get(){ Stringkey="S_COUNT"; Runnabler=newRunnable(){ @Override publicvoidrun(){ RAtomicLongatomicLong=redissonClient.getAtomicLong(key); if(!atomicLong.isExists()){ atomicLong.set(300l); } if(atomicLong.get()>0){ longl=atomicLong.getAndDecrement(); i--; System.out.println(Thread.currentThread().getName()+"->"+i+"->"+l); } } }; while(i!=0){ newThread(r).start(); //newThread(r).run(); //newThread(r).run(); //newThread(r).run(); //newThread(r).run(); } RBucketbucket=redissonClient.getBucket(key); Strings=bucket.get(); System.out.println("================线程已结束================================"+s); returns; } }

4.3 扩展

4.3.1 丰富的jar支持,尤其是对 Netty NIO框架

4.3.2 丰富的配置机制选择,这里是详细的配置说明

https://github.com/redisson/redisson/wiki/2.-Configuration

关于序列化机制中,就有很多

ebfcba9a-1668-11ec-8fb8-12bb97331649.pngec0676fc-1668-11ec-8fb8-12bb97331649.png

4.3.3 API支持(部分展示),具体的 Redis --> RedissonClient ,可查看这里

https://github.com/redisson/redisson/wiki/11.-Redis-commands-mapping

ec127c54-1668-11ec-8fb8-12bb97331649.png


4.3.4 轻便的丰富的锁机制的实现

Lock

Fair Lock

MultiLock

RedLock

ReadWriteLock

Semaphore

PermitExpirableSemaphore

CountDownLatch

四、基于注解实现的Redis缓存4.1 Maven 和 YML配置

参考 RedisTemplate 配置。另外,还需要额外的配置类


	

//todo定义序列化,解决乱码问题 @EnableCaching @Configuration @ConfigurationProperties(prefix="spring.cache.redis") publicclassRedisCacheConfig{ privateDurationtimeToLive=Duration.ZERO; publicvoidsetTimeToLive(DurationtimeToLive){ this.timeToLive=timeToLive; } @Bean publicCacheManagercacheManager(RedisConnectionFactoryfactory){ RedisSerializerredisSerializer=newStringRedisSerializer(); Jackson2JsonRedisSerializerjackson2JsonRedisSerializer=newJackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapperom=newObjectMapper(); om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); //配置序列化(解决乱码的问题) RedisCacheConfigurationconfig=RedisCacheConfiguration.defaultCacheConfig() .entryTtl(timeToLive) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManagercacheManager=RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); returncacheManager; } }

4.2 使用示例


	

@Transactional @Service publicclassReImplimplementsRedisService{ @Resource privateCustomerRepocustomerRepo; @Resource privateStringRedisTemplatestringRedisTemplate; publicstaticfinalStringREDIS_CUSTOMERS_ONE="Customers"; publicstaticfinalStringREDIS_CUSTOMERS_ALL="allList"; //=====================================================================使用Springcahce注解方式实现缓存 //==================================单个操作 @Override @Cacheable(value="cache:customer",unless="null==#result",key="#id") publicCustomersEntitycacheOne(Integerid){ finalOptionalbyId=customerRepo.findById(id); returnbyId.isPresent()?byId.get():null; } @Override @Cacheable(value="cache:customer",unless="null==#result",key="#id") publicCustomersEntitycacheOne2(Integerid){ finalOptionalbyId=customerRepo.findById(id); returnbyId.isPresent()?byId.get():null; } //todo自定义redis缓存的key, @Override @Cacheable(value="cache:customer",unless="null==#result",key="#root.methodName+'.'+#id") publicCustomersEntitycacheOne3(Integerid){ finalOptionalbyId=customerRepo.findById(id); returnbyId.isPresent()?byId.get():null; } //todo这里缓存到redis,还有响应页面是String(加了很多转义符,),不是Json格式 @Override @Cacheable(value="cache:customer",unless="null==#result",key="#root.methodName+'.'+#id") publicStringcacheOne4(Integerid){ finalOptionalbyId=customerRepo.findById(id); returnbyId.map(JSONUtil::toJsonStr).orElse(null); } //todo缓存json,不乱码已处理好,调整序列化和反序列化 @Override @Cacheable(value="cache:customer",unless="null==#result",key="#root.methodName+'.'+#id") publicCustomersEntitycacheOne5(Integerid){ OptionalbyId=customerRepo.findById(id); returnbyId.filter(obj->!StrUtil.isBlankIfStr(obj)).orElse(null); } //==================================删除缓存 @Override @CacheEvict(value="cache:customer",key="'cacheOne5'+'.'+#id") publicObjectdel(Integerid){ //删除缓存后的逻辑 returnnull; } @Override @CacheEvict(value="cache:customer",allEntries=true) publicvoiddel(){ } @CacheEvict(value="cache:all",allEntries=true) publicvoiddelall(){ } //==================List操作 @Override @Cacheable(value="cache:all") publicListcacheList(){ Listall=customerRepo.findAll(); returnall; } //todo先查询缓存,再校验是否一致,然后更新操作,比较实用,要清楚缓存的数据格式(明确业务和缓存模型数据) @Override @CachePut(value="cache:all",unless="null==#result",key="#root.methodName") publicListcacheList2(){ Listall=customerRepo.findAll(); returnall; } }

4.3 扩展

基于spring缓存实现

来源:blog.csdn.net/qq_42105629/article/details/102589319

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • spring
    +关注

    关注

    0

    文章

    340

    浏览量

    14338
  • Boot
    +关注

    关注

    0

    文章

    149

    浏览量

    35823
  • Redis
    +关注

    关注

    0

    文章

    374

    浏览量

    10871
  • SpringBoot
    +关注

    关注

    0

    文章

    173

    浏览量

    177

原文标题:Spring Boot 操作 Redis 的各种实现

文章出处:【微信号:AndroidPush,微信公众号:Android编程精选】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Redis缓存与Memcached的比较

    关键特性和差异: 1. 数据存储 Redis: Redis是一个开源的键值存储,支持多种数据结构,如字符串、列表、集合、有序集合、散列、位图、超日志和地理空间索引。 它支持持久化,可以将内存中的数据保存到磁盘,支持RDB(快照)
    的头像 发表于 12-18 09:33 98次阅读

    nginx+lua+redis实现灰度发布

    作者:马仁喜 前言: 授人以鱼不如授人以渔 .先学会用,在学原理,在学创造,可能一辈子用不到这种能力,但是不能不具备这种能力。这篇文章主要是沉淀使用nginx+lua+redis实现灰度,当我们具备
    的头像 发表于 12-17 10:01 43次阅读

    恒讯科技分析:云数据库rds和redis区别是什么如何选择?

    结构化数据,使用SQL作为查询语言,支持ACID事务和多种复杂查询操作。而Redis是一个基于内存的非关系型数据库,采用键值对模型存储数据,支持丰富的数据结构如字符串、列表、集合、哈希表等。 2、性能:
    的头像 发表于 08-19 15:31 378次阅读

    Redis 开源协议调整,我们怎么办?

    2 024 年 3 月 20 日, Redis 官方宣布,从 Redis 7.4 版本开始,Redis 将获得源可用许可证 ( RSALv2 ) 和服务器端公共许可证 ( SSPLv1 ) 的双重
    的头像 发表于 05-09 22:59 429次阅读
    <b class='flag-5'>Redis</b> 开源协议调整,我们怎么办?

    Redis开源版与Redis企业版,怎么选用?

    点击“蓝字”关注我们数以千计的企业和数以百万计的开发人员Redis开源版来构建应用程序。但随着用户数量、数据量和地区性的增加,成本、可扩展性、运营和可用性等问题也随之而来。Redis企业版
    的头像 发表于 04-04 08:04 1047次阅读
    <b class='flag-5'>Redis</b>开源版与<b class='flag-5'>Redis</b>企业版,怎么选用?

    数据安全没保障?GaussDB(for Redis) 为你保驾护航

    近日,一些用户反馈,使用的开源 Redis 中新增了几个未知来源的 Key。通过分析发现,用户使用的开源 Redis 没有设置密码,很可能是遭到了 Redis 扩散病毒的攻击,表面上只是新增了几个
    的头像 发表于 03-28 22:09 673次阅读
    数据安全没保障?GaussDB(for <b class='flag-5'>Redis</b>) 为你保驾护航

    GaussDB(for Redis) 特性揭秘:多租户管理

    级鉴权能力,即可约束每个账号可访问的数据库(DB)范围,避免误操作其他租户数据。该特性可以帮助企业在共享 Redis 实例的情况下,保护不同租户的数据安全,为企业的开发和管理提供便利。 哪些用户需要使用多租户功能? 多租户是数据库用户刚需的一个功能。例如,企业中有两个业
    的头像 发表于 03-28 22:06 742次阅读
    GaussDB(for <b class='flag-5'>Redis</b>) 特性揭秘:多租户管理

    GaussDB(for Redis) 特性揭秘:大 key 治理

      从 DBA 的视角看,大 Key 无疑是引起 Redis 线上问题的常见原因。为了解决大 Key 隐患,业务首先要遵守合理的开发规范,减少大 Key 的产生和访问依赖。但有时大 Key 是在程序
    的头像 发表于 03-28 22:06 663次阅读
    GaussDB(for <b class='flag-5'>Redis</b>) 特性揭秘:大 key 治理

    GaussDB(for Redis) 游戏实践:玩家下线行为上报

    实现以上功能时,感知用户下线行为延迟较大,导致上报时间不准确。华为云 GaussDB(for Redis)作为一款企业级游戏数据库,具备卓越的企业级能力,能及时上报用户下线行为,并被广泛应用于排行榜等多种业务场景。 基于
    的头像 发表于 03-28 22:03 519次阅读

    新版 Redis 不再“开源”,对使用者都有哪些影响?

    2024 年 3 月 20 日,Redis Labs 宣布从 Redis 7.4 开始,将原先比较宽松的 BSD 源码使用协议修改为 RSAv2和 SSPLv1协议。该变化意味着 Redis
    的头像 发表于 03-27 22:30 488次阅读
    新版 <b class='flag-5'>Redis</b> 不再“开源”,对使用者都有哪些影响?

    Redis实现分布式多规则限流的方式介绍

    市面上很多介绍 Redis 如何实现限流的,但是大部分都有一个缺点,就是只能实现单一的限流,比如 1 分钟访问 1 次或者 60 分钟访问 10 次这种,但是如果想一个接口两种规则都需要满足呢,我们的项目又是分布式项目,应该如何
    的头像 发表于 02-26 10:07 489次阅读
    <b class='flag-5'>Redis</b><b class='flag-5'>实现</b>分布式多规则限流的方式介绍

    Redis官方搜索引擎来了,性能炸裂!

    RediSearch 是一个 Redis 模块,为 Redis 提供查询、二级索引和全文搜索功能。
    的头像 发表于 02-21 10:01 2321次阅读
    <b class='flag-5'>Redis</b>官方搜索引擎来了,性能炸裂!

    Redis可以实现消息中间件MQ的功能

    是一种通信模式:发送者(PUBLISH)发送消息,订阅者(SUBSCRIBE)接收消息,可以实现进程间的消息传递   Redis可以实现消息中间件MQ的功能,通过发布订阅实现消息
    的头像 发表于 01-25 14:48 926次阅读
    <b class='flag-5'>Redis</b>可以<b class='flag-5'>实现</b>消息中间件MQ的功能

    Redis7单线程与多线程详解

    主要是指Redis的网络IO和键值对读写是由一个线程来完成的。
    的头像 发表于 01-16 17:33 1848次阅读
    <b class='flag-5'>Redis</b>7单线程与多线程详解

    linux下Redis常用命令使用

    redis重启,缓存数据还在,redis清缓存数据
    的头像 发表于 12-27 09:56 6510次阅读
    linux下<b class='flag-5'>Redis</b>常用命令使用