SpringBoot中整合Redis(緩存篇)
注意:文末有最新Java實戰(zhàn)項目和面試題
作者丨艾神一不小心
juejin.im/post/5b1f35ac6fb9a01e631e24fc
一、安裝



二、整合到springboot
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-data-redisartifactId>
????????dependency>
##默認密碼為空
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?
@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;
????}
}
/**
?* 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);
}
@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);
????}
}
三、測試
@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());
????}
}

四、項目實戰(zhàn)
@EnableCaching??//開啟緩存
@SpringBootApplication
public?class?PoetryApplication?{
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(PoetryApplication.class,?args);
????}
}
@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);
????}
}
---END--- 文末福利
評論
圖片
表情


