<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>

          SpringBoot中整合Redis(緩存篇)

          共 9692字,需瀏覽 20分鐘

           ·

          2020-10-23 14:00


          注意文末有最新Java實戰(zhàn)項目面試題


          作者丨艾神一不小心

          juejin.im/post/5b1f35ac6fb9a01e631e24fc


          實際開發(fā)中緩存處理是必須的,不可能我們每次客戶端去請求一次服務器,服務器每次都要去數(shù)據(jù)庫中進行查找,為什么要使用緩存?說到底是為了提高系統(tǒng)的運行速度。將用戶頻繁訪問的內(nèi)容存放在離用戶最近,訪問速度最快的地方,提高用戶的響應速度,今天先來講下在springboot中整合redis的詳細步驟。

          一、安裝

          redis下載地址:
          https://redis.io/download
          首先要在本地安裝一個redis程序,安裝過程十分簡單(略過),安裝完成后進入到redis文件夾中可以看到如下:
          點擊redis-server.exe開啟redis服務,可以看到如下圖所示即代表開啟redis服務成功:
          那么我們可以開啟redis客戶端進行測試:

          二、整合到springboot

          1、在項目中加入redis依賴,pom文件中添加如下:

          ????????<dependency>
          ????????????<groupId>org.springframework.bootgroupId>

          ????????????<artifactId>spring-boot-starter-data-redisartifactId>
          ????????dependency>
          2、在application.yml中添加redis配置:
          ##默認密碼為空
          redis:
          ??????host:?127.0.0.1
          ??????#?Redis服務器連接端口
          ??????port:?6379
          ??????jedis:
          ????????pool:
          ??????????#連接池最大連接數(shù)(使用負值表示沒有限制)
          ??????????max-active:?100
          ??????????#?連接池中的最小空閑連接
          ??????????max-idle:?10
          ??????????#?連接池最大阻塞等待時間(使用負值表示沒有限制)
          ??????????max-wait:?100000
          ??????#?連接超時時間(毫秒)
          ??????timeout:?5000
          ??????#默認是索引為0的數(shù)據(jù)庫
          ??????database:?0?
          3、新建RedisConfiguration配置類,繼承CachingConfigurerSupport,@EnableCaching開啟注解
          @Configuration
          @EnableCaching
          public?class?RedisConfiguration?extends?CachingConfigurerSupport?{
          ????/**
          ?????*?自定義生成key的規(guī)則
          ?????*/

          ????@Override
          ????public?KeyGenerator?keyGenerator()?{
          ????????return?new?KeyGenerator()?{
          ????????????@Override
          ????????????public?Object?generate(Object?o,?Method?method,?Object...?objects)?{
          ????????????????//格式化緩存key字符串
          ????????????????StringBuilder?sb?=?new?StringBuilder();
          ????????????????//追加類名
          ????????????????sb.append(o.getClass().getName());
          ????????????????//追加方法名
          ????????????????sb.append(method.getName());
          ????????????????//遍歷參數(shù)并且追加
          ????????????????for?(Object?obj?:?objects)?{
          ????????????????????sb.append(obj.toString());
          ????????????????}
          ????????????????System.out.println("調(diào)用Redis緩存Key?:?"?+?sb.toString());
          ????????????????return?sb.toString();
          ????????????}
          ????????};
          ????}

          ????/**
          ?????*?采用RedisCacheManager作為緩存管理器
          ?????*?@param?connectionFactory
          ?????*/

          ????@Bean
          ????public?CacheManager?cacheManager(RedisConnectionFactory?connectionFactory)?{
          ????????RedisCacheManager?redisCacheManager?=?RedisCacheManager.create(connectionFactory);
          ????????return??redisCacheManager;
          ????}

          ????@Bean
          ????public?RedisTemplate?redisTemplate(RedisConnectionFactory?factory)?{
          ????????////解決鍵、值序列化問題
          ????????StringRedisTemplate?template?=?new?StringRedisTemplate(factory);
          ????????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.setValueSerializer(jackson2JsonRedisSerializer);
          ????????template.afterPropertiesSet();
          ????????return?template;
          ????}
          }
          4、創(chuàng)建自定義的接口來定義需要的redis的功能
          /**
          ?* K 指以hash結(jié)構(gòu)操作時?鍵類型
          ?*?T?為數(shù)據(jù)實體?應實現(xiàn)序列化接口,并定義serialVersionUID?*?RedisTemplate?提供了五種數(shù)據(jù)結(jié)構(gòu)操作類型?hash?/?list?/?set?/?zset?/?value
          ?*?方法命名格式為?數(shù)據(jù)操作類型?+?操作?如 hashPut 指以hash結(jié)構(gòu)(也就是map)想key添加鍵值對?
          ?*/

          public?interface?RedisHelper<HK,?T>?{
          ????/**
          ?????*?Hash結(jié)構(gòu)?添加元素?*?@param?key?key?*?@param?hashKey?hashKey?*?@param?domain?元素
          ?????*/

          ????void?hashPut(String?key,?HK?hashKey,?T?domain);

          ????/**
          ?????*?Hash結(jié)構(gòu)?獲取指定key所有鍵值對?*?@param?key?*?@return
          ?????*/

          ????Map?hashFindAll(String?key);

          ????/**
          ?????*?Hash結(jié)構(gòu)?獲取單個元素?*?@param?key?*?@param?hashKey?*?@return
          ?????*/

          ????T?hashGet(String?key,?HK?hashKey);

          ????void?hashRemove(String?key,?HK?hashKey);

          ????/**
          ?????*?List結(jié)構(gòu)?向尾部(Right)添加元素?*?@param?key?*?@param?domain?*?@return
          ?????*/

          ????Long?listPush(String?key,?T?domain);

          ????/**
          ?????*?List結(jié)構(gòu)?向頭部(Left)添加元素?*?@param?key?*?@param?domain?*?@return
          ?????*/

          ????Long?listUnshift(String?key,?T?domain);

          ????/**
          ?????*?List結(jié)構(gòu)?獲取所有元素?*?@param?key?*?@return
          ?????*/

          ????List?listFindAll(String?key);

          ????/**
          ?????*?List結(jié)構(gòu)?移除并獲取數(shù)組第一個元素?*?@param?key?*?@return
          ?????*/

          ????T?listLPop(String?key);

          ????/**
          ?????*?對象的實體類
          ?????*?@param?key
          ?????*?@param?domain
          ?????*?@return
          ?????*/

          ????void?valuePut(String?key,?T?domain);

          ????/**
          ?????*?獲取對象實體類
          ?????*?@param?key
          ?????*?@return
          ?????*/

          ????T?getValue(String?key);

          ????void?remove(String?key);

          ????/**
          ?????*?設置過期時間?*?@param?key?鍵?*?@param?timeout?時間?*?@param?timeUnit?時間單位
          ?????*/

          ????boolean?expirse(String?key,?long?timeout,?TimeUnit?timeUnit);
          }
          下面是創(chuàng)建RedisHelperImpl進行接口的實現(xiàn)
          @Service("RedisHelper")
          public?class?RedisHelperImpl<HK,?T>?implements?RedisHelper<HK,?T>?{
          ????//?在構(gòu)造器中獲取redisTemplate實例,?key(not?hashKey)?默認使用String類型
          ????private?RedisTemplate?redisTemplate;
          ????//?在構(gòu)造器中通過redisTemplate的工廠方法實例化操作對象
          ????private?HashOperations?hashOperations;
          ????private?ListOperations?listOperations;
          ????private?ZSetOperations?zSetOperations;
          ????private?SetOperations?setOperations;
          ????private?ValueOperations?valueOperations;

          ????//?IDEA雖然報錯,但是依然可以注入成功,?實例化操作對象后就可以直接調(diào)用方法操作Redis數(shù)據(jù)庫
          ????@Autowired
          ????public?RedisHelperImpl(RedisTemplate?redisTemplate)?{
          ????????this.redisTemplate?=?redisTemplate;
          ????????this.hashOperations?=?redisTemplate.opsForHash();
          ????????this.listOperations?=?redisTemplate.opsForList();
          ????????this.zSetOperations?=?redisTemplate.opsForZSet();
          ????????this.setOperations?=?redisTemplate.opsForSet();
          ????????this.valueOperations?=?redisTemplate.opsForValue();
          ????}

          ????@Override
          ????public?void?hashPut(String?key,?HK?hashKey,?T?domain)?{
          ????????hashOperations.put(key,?hashKey,?domain);
          ????}

          ????@Override
          ????public?Map?hashFindAll(String?key)?{
          ????????return?hashOperations.entries(key);
          ????}

          ????@Override
          ????public?T?hashGet(String?key,?HK?hashKey)?{
          ????????return?hashOperations.get(key,?hashKey);
          ????}

          ????@Override
          ????public?void?hashRemove(String?key,?HK?hashKey)?{
          ????????hashOperations.delete(key,?hashKey);
          ????}

          ????@Override
          ????public?Long?listPush(String?key,?T?domain)?{
          ????????return?listOperations.rightPush(key,?domain);
          ????}

          ????@Override
          ????public?Long?listUnshift(String?key,?T?domain)?{
          ????????return?listOperations.leftPush(key,?domain);
          ????}

          ????@Override
          ????public?List?listFindAll(String?key)?{
          ????????if?(!redisTemplate.hasKey(key))?{
          ????????????return?null;
          ????????}
          ????????return?listOperations.range(key,?0,?listOperations.size(key));
          ????}

          ????@Override
          ????public?T?listLPop(String?key)?{
          ????????return?listOperations.leftPop(key);
          ????}

          ????@Override
          ????public?void?valuePut(String?key,?T?domain)?{
          ????????valueOperations.set(key,?domain);
          ????}

          ????@Override
          ????public?T?getValue(String?key)?{
          ????????return?valueOperations.get(key);
          ????}

          ????@Override
          ????public?void?remove(String?key)?{
          ????????redisTemplate.delete(key);
          ????}

          ????@Override
          ????public?boolean?expirse(String?key,?long?timeout,?TimeUnit?timeUnit)?{
          ????????return?redisTemplate.expire(key,?timeout,?timeUnit);
          ????}
          }

          三、測試

          編寫TestRedis類進行測試
          @RunWith(SpringRunner.class)
          @SpringBootTest
          public?class?TestRedis?{

          ????@Autowired
          ????private?StringRedisTemplate?stringRedisTemplate;

          ????@Autowired
          ????private?RedisTemplate?redisTemplate;

          ????@Autowired
          ????private?RedisHelperImpl?redisHelper;

          ????@Test
          ????public?void?test()?throws?Exception{
          //????????基本寫法
          //????????stringRedisTemplate.opsForValue().set("aaa","111");
          //????????Assert.assertEquals("111",stringRedisTemplate.opsForValue().get("aaa"));
          //????????System.out.println(stringRedisTemplate.opsForValue().get("aaa"));
          ????????Author?user=new?Author();
          ????????user.setName("Alex");
          ????????user.setIntro_l("不會打籃球的程序不是好男人");
          ????????redisHelper.valuePut("aaa",user);
          ????????System.out.println(redisHelper.getValue("aaa"));
          ????}

          ????@Test
          ????public?void?testObj()?throws?Exception?{
          ????????Author?user=new?Author();
          ????????user.setName("Jerry");
          ????????user.setIntro_l("不會打籃球的程序不是好男人!");

          ????????ValueOperations?operations=redisTemplate.opsForValue();
          ????????operations.set("502",?user);
          ????????Thread.sleep(500);
          ????????boolean?exists=redisTemplate.hasKey("502");
          ????????if(exists){
          ????????????System.out.println(redisTemplate.opsForValue().get("502"));
          ????????}else{
          ????????????System.out.println("exists?is?false");
          ????????}
          ????????//?Assert.assertEquals("aa",?operations.get("com.neo.f").getUserName());
          ????}
          }
          運行TestRedis測試類,結(jié)果如下:
          注意:如果在RedisConfiguration中不配置redisTemplate(RedisConnectionFactory factory)注解,會造成鍵、值的一個序列化問題,有興趣的可以去試一下。

          四、項目實戰(zhàn)

          首先需要在程序的入口處Application中添加@EnableCaching開啟緩存的注解
          @EnableCaching??//開啟緩存
          @SpringBootApplication
          public?class?PoetryApplication?{

          ????public?static?void?main(String[]?args)?{
          ????????SpringApplication.run(PoetryApplication.class,?args);
          ????}
          }
          上面的redis相關(guān)寫法是我們自定義設置并獲取的,那么我們經(jīng)常要在訪問接口的地方去使用redis進行緩存相關(guān)實體對象以及集合等,那么我們怎么實現(xiàn)呢?
          比如我現(xiàn)在想在AuthorController中去緩存作者相關(guān)信息的緩存數(shù)據(jù),該怎么辦呢?如下:
          @RestController
          @RequestMapping(value?=?"/poem")
          public?class?AuthorController?{

          ????private?final?static?Logger?logger?=?LoggerFactory.getLogger(AuthorController.class);

          ????@Autowired
          ????private?AuthorRepository?authorRepository;

          ????@Cacheable(value="poemInfo")??//自動根據(jù)方法生成緩存
          ????@PostMapping(value?=?"/poemInfo")
          ????public?Result?author(@RequestParam("author_id")?int?author_id,?@RequestParam("author_name")String?author_name)?{
          ????????if(StringUtils.isEmpty(author_id)?||?StringUtils.isEmpty(author_name)){
          ????????????return?ResultUtils.error(ResultCode.INVALID_PARAM_EMPTY);
          ????????}
          ????????Author?author;
          ????????Optional?optional?=?authorRepository.getAuthorByIdAndName(author_id,?author_name);
          ????????if?(optional.isPresent())?{
          ????????????author?=?optional.get();
          ????????????//通過\n或者多個空格?進行過濾去重
          ????????????if?(!StringUtils.isEmpty(author.getIntro_l()))?{
          ????????????????String?s?=?author.getIntro_l();
          ????????????????String?intro?=?s.split("\\s?+")[0];
          ????????????????author.setIntro_l(intro);
          ????????????}
          ????????}?else?{
          ???????????return?ResultUtils.error(ResultCode.NO_FIND_THINGS);
          ????????}
          ????????return?ResultUtils.ok(author);
          ????}
          }
          這里 @Cacheable(value="poemInfo")這個注解的意思就是自動根據(jù)方法生成緩存,value就是緩存下來的key。到這里我們就已經(jīng)把redis整合到了springboot中了。

          ---END---
          文末福利




          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  伊人久久青青操 | 日本A片免费看 | 91精品国产综合久久蜜芽解析速度 | 69久人妻无码精品一区 | 躁BBB躁BBB躁BBBBBB日 |