<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Boot + Redis 實(shí)現(xiàn)各種操作,寫得太好了吧!

          共 13247字,需瀏覽 27分鐘

           ·

          2021-10-03 19:48

          關(guān)注我們,設(shè)為星標(biāo),每天7:30不見不散,架構(gòu)路上與您共享?

          回復(fù)"架構(gòu)師"獲取資源

          一、Jedis,Redisson,Lettuce三者的區(qū)別

          共同點(diǎn):都提供了基于Redis操作的Java API,只是封裝程度,具體實(shí)現(xiàn)稍有不同。

          不同點(diǎn):

          1.1、Jedis

          是Redis的Java實(shí)現(xiàn)的客戶端。支持基本的數(shù)據(jù)類型如:String、Hash、List、Set、Sorted Set。

          特點(diǎn):使用阻塞的I/O,方法調(diào)用同步,程序流需要等到socket處理完I/O才能執(zhí)行,不支持異步操作。Jedis客戶端實(shí)例不是線程安全的,需要通過連接池來使用Jedis。

          1.2、Redisson

          優(yōu)點(diǎn)點(diǎn):分布式鎖,分布式集合,可通過Redis支持延遲隊(duì)列。

          1.3、 Lettuce

          用于線程安全同步,異步和響應(yīng)使用,支持集群,Sentinel,管道和編碼器。

          基于Netty框架的事件驅(qū)動(dòng)的通信層,其方法調(diào)用是異步的。Lettuce的API是線程安全的,所以可以操作單個(gè)Lettuce連接來完成各種操作。

          二、RedisTemplate

          2.1、使用配置

          maven配置引入,(要加上版本號(hào),我這里是因?yàn)镻arent已聲明)


          ????org.springframework.boot
          ????spring-boot-starter-data-redis

          application-dev.yml

          spring:
          ??redis:
          ????host:?192.168.1.140
          ????port:?6379
          ????password:
          ????database:?15?#?指定redis的分庫(共16個(gè)0到15)

          2.2、使用示例

          ?@Resource
          ?private?StringRedisTemplate?stringRedisTemplate;
          ?
          ????@Override
          ????public?CustomersEntity?findById(Integer?id)?{
          ????????//?需要緩存
          ????????//?所有涉及的緩存都需要?jiǎng)h除,或者更新
          ????????try?{
          ????????????String?toString?=?stringRedisTemplate.opsForHash().get(REDIS_CUSTOMERS_ONE,?id?+?"").toString();
          ????????????if?(toString?!=?null)?{
          ????????????????return?JSONUtil.toBean(toString,?CustomersEntity.class);
          ????????????}
          ????????}?catch?(Exception?e)?{
          ????????????e.printStackTrace();
          ????????}
          ????????//?緩存為空的時(shí)候,先查,然后緩存redis
          ????????Optional?byId?=?customerRepo.findById(id);
          ????????if?(byId.isPresent())?{
          ????????????CustomersEntity?customersEntity?=?byId.get();
          ????????????try?{
          ????????????????stringRedisTemplate.opsForHash().put(REDIS_CUSTOMERS_ONE,?id?+?"",?JSONUtil.toJsonStr(customersEntity));
          ????????????}?catch?(Exception?e)?{
          ????????????????e.printStackTrace();
          ????????????}
          ????????????return?customersEntity;
          ????????}
          ????????return?null;
          ????}

          2.3、擴(kuò)展

          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默認(rèn)序列化機(jī)制
          public?class?StringRedisTemplate?extends?RedisTemplate?{

          ?????/**
          ??????*?Constructs?a?new?StringRedisTemplate?instance.?{@link?#setConnectionFactory(RedisConnectionFactory)}
          ??????*?and?{@link?#afterPropertiesSet()}?still?need?to?be?called.
          ??????*/
          ?????public?StringRedisTemplate()?{
          ??????RedisSerializer?stringSerializer?=?new?StringRedisSerializer();
          ??????setKeySerializer(stringSerializer);
          ??????setValueSerializer(stringSerializer);
          ??????setHashKeySerializer(stringSerializer);
          ??????setHashValueSerializer(stringSerializer);
          ?????}
          ?}

          三、RedissonClient 操作示例

          3.1 基本配置

          3.1.1、Maven pom 引入

          ????org.springframework.boot
          ????spring-boot-starter-data-redis


          ????org.redisson
          ????redisson
          ????3.8.2
          ????true


          ????org.redisson
          ????redisson-spring-boot-starter
          ????LATEST

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

          redisson-config.yml。

          #?Redisson?配置
          singleServerConfig:
          ??address:?"redis://192.168.1.140:6379"
          ??password:?null
          ??clientName:?null
          ??database:?15?#選擇使用哪個(gè)數(shù)據(jù)庫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
          public?class?RedissonConfig?{

          ????@Bean
          ????public?RedissonClient?redisson()?throws?IOException?{

          ????????//?兩種讀取方式,Config.fromYAML?和?Config.fromJSON
          //????????Config?config?=?Config.fromJSON(RedissonConfig.class.getClassLoader().getResource("redisson-config.json"));
          ????????Config?config?=?Config.fromYAML(RedissonConfig.class.getClassLoader().getResource("redisson-config.yml"));
          ????????return?Redisson.create(config);
          ????}
          }

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

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

          3.2 使用示例

          @RestController
          @RequestMapping("/")
          public?class?TeController?{

          ????@Autowired
          ????private?RedissonClient?redissonClient;

          ????static?long?i?=?20;
          ????static?long?sum?=?300;

          //????==========================?String?=======================
          ????@GetMapping("/set/{key}")
          ????public?String?s1(@PathVariable?String?key)?{
          ????????//?設(shè)置字符串
          ????????RBucket?keyObj?=?redissonClient.getBucket(key);
          ????????keyObj.set(key?+?"1-v1");
          ????????return?key;
          ????}

          ????@GetMapping("/get/{key}")
          ????public?String?g1(@PathVariable?String?key)?{
          ????????//?設(shè)置字符串
          ????????RBucket?keyObj?=?redissonClient.getBucket(key);
          ????????String?s?=?keyObj.get();
          ????????return?s;
          ????}

          ????//????==========================?hash?=======================-=

          ????@GetMapping("/hset/{key}")
          ????public?String?h1(@PathVariable?String?key)?{

          ????????Ur?ur?=?new?Ur();
          ????????ur.setId(MathUtil.randomLong(1,20));
          ????????ur.setName(key);
          ??????//?存放?Hash
          ????????RMap?ss?=?redissonClient.getMap("UR");
          ????????ss.put(ur.getId().toString(),?ur);
          ????????return?ur.toString();
          ????}

          ????@GetMapping("/hget/{id}")
          ????public?String?h2(@PathVariable?String?id)?{
          ????????//?hash?查詢
          ????????RMap?ss?=?redissonClient.getMap("UR");
          ????????Ur?ur?=?ss.get(id);
          ????????return?ur.toString();
          ????}

          ????//?查詢所有的?keys
          ????@GetMapping("/all")
          ????public?String?all(){
          ????????RKeys?keys?=?redissonClient.getKeys();
          ????????Iterable?keys1?=?keys.getKeys();
          ????????keys1.forEach(System.out::println);
          ????????return?keys.toString();
          ????}

          ????//?==================?==============讀寫鎖測(cè)試?=============================

          ????@GetMapping("/rw/set/{key}")
          ????public?void?rw_set(){
          //????????RedissonLock.
          ????????RBucket?ls_count?=?redissonClient.getBucket("LS_COUNT");
          ????????ls_count.set("300",360000000l,?TimeUnit.SECONDS);
          ????}

          ????//?減法運(yùn)算
          ????@GetMapping("/jf")
          ????public?void?jf(){

          ????????String?key?=?"S_COUNT";

          //????????RAtomicLong?atomicLong?=?redissonClient.getAtomicLong(key);
          //????????atomicLong.set(sum);
          //????????long?l?=?atomicLong.decrementAndGet();
          //????????System.out.println(l);

          ????????RAtomicLong?atomicLong?=?redissonClient.getAtomicLong(key);
          ????????if?(!atomicLong.isExists())?{
          ????????????atomicLong.set(300l);
          ????????}

          ????????while?(i?==?0)?{
          ????????????if?(atomicLong.get()?>?0)?{
          ????????????????long?l?=?atomicLong.getAndDecrement();
          ????????????????????????try?{
          ????????????????????????????Thread.sleep(1000l);
          ????????????????????????}?catch?(InterruptedException?e)?{
          ????????????????????????????e.printStackTrace();
          ????????????????????????}
          ????????????????i?--;
          ????????????????System.out.println(Thread.currentThread().getName()?+?"->"?+?i?+?"->"?+?l);
          ????????????}
          ????????}


          ????}

          ????@GetMapping("/rw/get")
          ????public?String?rw_get(){

          ????????String?key?=?"S_COUNT";
          ????????Runnable?r?=?new?Runnable()?{
          ????????????@Override
          ????????????public?void?run()?{
          ????????????????RAtomicLong?atomicLong?=?redissonClient.getAtomicLong(key);
          ????????????????if?(!atomicLong.isExists())?{
          ????????????????????atomicLong.set(300l);
          ????????????????}
          ????????????????if?(atomicLong.get()?>?0)?{
          ????????????????????long?l?=?atomicLong.getAndDecrement();
          ????????????????????i?--;
          ????????????????????System.out.println(Thread.currentThread().getName()?+?"->"?+?i?+?"->"?+?l);
          ????????????????}
          ????????????}
          ????????};

          ????????while?(i?!=?0)?{
          ????????????new?Thread(r).start();
          //????????????new?Thread(r).run();
          //????????????new?Thread(r).run();
          //????????????new?Thread(r).run();
          //????????????new?Thread(r).run();
          ????????}


          ????????RBucket?bucket?=?redissonClient.getBucket(key);
          ????????String?s?=?bucket.get();
          ????????System.out.println("================線程已結(jié)束================================"?+?s);

          ????????return?s;
          ????}

          }

          4.3 擴(kuò)展

          4.3.1 豐富的jar支持,尤其是對(duì) Netty NIO框架

          4.3.2 豐富的配置機(jī)制選擇,這里是詳細(xì)的配置說明

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

          關(guān)于序列化機(jī)制中,就有很多

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

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

          4.3.4 輕便的豐富的鎖機(jī)制的實(shí)現(xiàn)

          • Lock
          • Fair Lock
          • MultiLock
          • RedLock
          • ReadWriteLock
          • Semaphore
          • PermitExpirableSemaphore
          • CountDownLatch

          四、基于注解實(shí)現(xiàn)的Redis緩存

          4.1 Maven 和 YML配置

          參考 RedisTemplate 配置。另外,還需要額外的配置類

          //?todo?定義序列化,解決亂碼問題
          @EnableCaching
          @Configuration
          @ConfigurationProperties(prefix?=?"spring.cache.redis")
          public?class?RedisCacheConfig?{

          ????private?Duration?timeToLive?=?Duration.ZERO;

          ????public?void?setTimeToLive(Duration?timeToLive)?{
          ????????this.timeToLive?=?timeToLive;
          ????}

          ????@Bean
          ????public?CacheManager?cacheManager(RedisConnectionFactory?factory)?{
          ????????RedisSerializer?redisSerializer?=?new?StringRedisSerializer();
          ????????Jackson2JsonRedisSerializer?jackson2JsonRedisSerializer?=?new?Jackson2JsonRedisSerializer(Object.class);

          ????????//?解決查詢緩存轉(zhuǎn)換異常的問題
          ????????ObjectMapper?om?=?new?ObjectMapper();
          ????????om.setVisibility(PropertyAccessor.ALL,?JsonAutoDetect.Visibility.ANY);
          ????????om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
          ????????jackson2JsonRedisSerializer.setObjectMapper(om);

          ????????//?配置序列化(解決亂碼的問題)
          ????????RedisCacheConfiguration?config?=?RedisCacheConfiguration.defaultCacheConfig()
          ????????????????.entryTtl(timeToLive)
          ????????????????.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
          ????????????????.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
          ????????????????.disableCachingNullValues();

          ????????RedisCacheManager?cacheManager?=?RedisCacheManager.builder(factory)
          ????????????????.cacheDefaults(config)
          ????????????????.build();
          ????????return?cacheManager;
          ????}

          }

          4.2 使用示例

          @Transactional
          @Service
          public?class?ReImpl?implements?RedisService?{

          ????@Resource
          ????private?CustomerRepo?customerRepo;
          ????@Resource
          ????private?StringRedisTemplate?stringRedisTemplate;

          ????public?static?final?String?REDIS_CUSTOMERS_ONE?=?"Customers";

          ????public?static?final?String?REDIS_CUSTOMERS_ALL?=?"allList";

          ????//?=====================================================================使用Spring?cahce?注解方式實(shí)現(xiàn)緩存
          ????//?==================================單個(gè)操作

          ????@Override
          ????@Cacheable(value?=?"cache:customer",?unless?=?"null?==?#result",key?=?"#id")
          ????public?CustomersEntity?cacheOne(Integer?id)?{
          ????????final?Optional?byId?=?customerRepo.findById(id);
          ????????return?byId.isPresent()???byId.get()?:?null;
          ????}

          ????@Override
          ????@Cacheable(value?=?"cache:customer",?unless?=?"null?==?#result",?key?=?"#id")
          ????public?CustomersEntity?cacheOne2(Integer?id)?{
          ????????final?Optional?byId?=?customerRepo.findById(id);
          ????????return?byId.isPresent()???byId.get()?:?null;
          ????}

          ?????//?todo?自定義redis緩存的key,
          ????@Override
          ????@Cacheable(value?=?"cache:customer",?unless?=?"null?==?#result",?key?=?"#root.methodName?+?'.'?+?#id")
          ????public?CustomersEntity?cacheOne3(Integer?id)?{
          ????????final?Optional?byId?=?customerRepo.findById(id);
          ????????return?byId.isPresent()???byId.get()?:?null;
          ????}

          ????//?todo?這里緩存到redis,還有響應(yīng)頁面是String(加了很多轉(zhuǎn)義符\,),不是Json格式
          ????@Override
          ????@Cacheable(value?=?"cache:customer",?unless?=?"null?==?#result",?key?=?"#root.methodName?+?'.'?+?#id")
          ????public?String?cacheOne4(Integer?id)?{
          ????????final?Optional?byId?=?customerRepo.findById(id);
          ????????return?byId.map(JSONUtil::toJsonStr).orElse(null);
          ????}

          ?????//?todo?緩存json,不亂碼已處理好,調(diào)整序列化和反序列化
          ????@Override
          ????@Cacheable(value?=?"cache:customer",?unless?=?"null?==?#result",?key?=?"#root.methodName?+?'.'?+?#id")
          ????public?CustomersEntity?cacheOne5(Integer?id)?{
          ????????Optional?byId?=?customerRepo.findById(id);
          ????????return?byId.filter(obj?->?!StrUtil.isBlankIfStr(obj)).orElse(null);
          ????}



          ????//?==================================刪除緩存
          ????@Override
          ????@CacheEvict(value?=?"cache:customer",?key?=?"'cacheOne5'?+?'.'?+?#id")
          ????public?Object?del(Integer?id)?{
          ????????//?刪除緩存后的邏輯
          ????????return?null;
          ????}

          ????@Override
          ????@CacheEvict(value?=?"cache:customer",allEntries?=?true)
          ????public?void?del()?{

          ????}

          ????@CacheEvict(value?=?"cache:all",allEntries?=?true)
          ????public?void?delall()?{

          ????}
          ????//?==================List操作

          ????@Override
          ????@Cacheable(value?=?"cache:all")
          ????public?List?cacheList()?{
          ????????List?all?=?customerRepo.findAll();
          ????????return?all;
          ????}

          ????//?todo?先查詢緩存,再校驗(yàn)是否一致,然后更新操作,比較實(shí)用,要清楚緩存的數(shù)據(jù)格式(明確業(yè)務(wù)和緩存模型數(shù)據(jù))
          ????@Override
          ????@CachePut(value?=?"cache:all",unless?=?"null?==?#result",key?=?"#root.methodName")
          ????public?List?cacheList2()?{
          ????????List?all?=?customerRepo.findAll();
          ????????return?all;
          ????}

          }

          4.3 擴(kuò)展

          基于spring緩存實(shí)現(xiàn)


          文章來源:http://blog.csdn.net/qq_42105629/article/details/102589319




          到此文章就結(jié)束了。如果今天的文章對(duì)你在進(jìn)階架構(gòu)師的路上有新的啟發(fā)和進(jìn)步,歡迎轉(zhuǎn)發(fā)給更多人。歡迎加入架構(gòu)師社區(qū)技術(shù)交流群,眾多大咖帶你進(jìn)階架構(gòu)師,在后臺(tái)回復(fù)“加群”即可入群。







          這些年小編給你分享過的干貨

          1.SpringBoot物流管理項(xiàng)目,拿去學(xué)習(xí)吧(附源碼)

          2.ERP系統(tǒng),自帶進(jìn)銷存+財(cái)務(wù)+生產(chǎn)功能,拿來即用(附源碼)

          3.帶工作流的SpringBoot后臺(tái)管理項(xiàng)目快速開發(fā)(附源碼)
          4.最好的OA系統(tǒng),拿來即用,非常方便(附源碼)

          5.SpringBoot+Vue完整的外賣系統(tǒng),手機(jī)端和后臺(tái)管理,附源碼!

          6.SpringBoot+Vue 可視化拖拽編輯的大屏項(xiàng)目(附源碼)

          轉(zhuǎn)發(fā)在看就是最大的支持??

          瀏覽 32
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  珍藏3年极品人妻疯狂3p | 夜夜骚av.一区二区三区 | 国产成人免费观看 | 精品人妻一区二区三区蜜桃 | 外国操逼视频网站 |